prescottprue / react-redux-firebase

Redux bindings for Firebase. Includes React Hooks and Higher Order Components.
https://react-redux-firebase.com
MIT License
2.55k stars 558 forks source link

feat(docs): example for anonymous auth #679

Open mattvick opened 5 years ago

mattvick commented 5 years ago

This is a request to add a beginner example to the docs

Enabling the Anonymous Auth authentication provider lets you enforce user-specific Security and Firebase rules without requiring credentials from your users.

This seems to me like a common and useful use case. The Cloud Firestore Web Codelab tells developers to do this.

There are several issues requesting help with Anonymous Auth but no clear example of how to configure react-redux-firebase to work when the Anonymous Auth authentication provider has been enabled.

react-redux-firebase seems like an awesome package and it would be great if the documentation contained an example to help beginners struggling with this issue.

Steps to reproduce the issue

  1. Create a Cloud Firestore database
  2. Enable the Anonymous Auth authentication provider
  3. Git clone react-redux-firebase
  4. Configure the Firestore Complete Example to connect to the Cloud Firestore database created in the first step
  5. Add firebase.auth().signInAnonymously(); to /src/store.js after initialisation of firebase on line 14
  6. Run the example with yarn start
  7. Expect no errors
  8. See the following error in the console
Error with profile listener: Missing or insufficient permissions. FirebaseError: Missing or insufficient permissions.
    at new FirestoreError (http://localhost:3000/static/js/1.chunk.js:28253:24)
    at JsonProtoSerializer.fromRpcStatus (http://localhost:3000/static/js/1.chunk.js:34795:12)
    at JsonProtoSerializer.fromWatchChange (http://localhost:3000/static/js/1.chunk.js:35330:38)
    at PersistentListenStream.onMessage (http://localhost:3000/static/js/1.chunk.js:45432:39)
    at http://localhost:3000/static/js/1.chunk.js:45343:22
    at http://localhost:3000/static/js/1.chunk.js:45393:18
    at http://localhost:3000/static/js/1.chunk.js:36812:14

Versions of dependencies, browser and OS

mattvick commented 5 years ago

I've found a way to implement anonymous sign in.

@prescottprue is this a reasonable solution?

I'd be happy to create a PR that adds my tiny project to the examples. Let me know if you'd like me to do so.

Solution to anonymous sign in issue:

After initialisation of firebase and firestore call onAuthStateChanged() as follows:

// /src/firebase.js
firebase.initializeApp(config);
firebase.firestore();
firebase.auth().onAuthStateChanged(async user => {
  if (!user) {
    await firebase.auth().signInAnonymously();
  }
});

Don't pass userProfile: 'users' or useFirestoreForProfile: true to reactReduxFirebase() enhancer config as we don't need a 'users' collection in Firestore for anonymous users:

// /src/store.js
const enhancers = [
  reduxFirestore(firebase),
  reactReduxFirebase(firebase),
  // reactReduxFirebase(firebase, {
  //   userProfile: 'users',
  //   useFirestoreForProfile: true,
  // }),
];

Create a root AuthLoading component that loads TodoList component once state.firestore.auth is set:

// /src/AuthLoading.js
const AuthLoading = ({ auth }) => {
  if (isEmpty(auth) || !isLoaded(auth)) {
    return null; // or return a loader component
  }
  return (
    <TodoList />
  );
}

export default compose(
  connect(({ firestore }) => ({
    auth: firestore.auth,
  })),
  firestoreConnect(),
)(AuthLoading);

Cloud Firestore database rules:

service cloud.firestore {
  match /databases/{database}/documents {
    // Todos:
    //   - Authenticated user can read
    //   - Authenticated user can create/update (for demo)
    //   - Validate updates
    //   - Deletes are not allowed
    match /todos/{todoId} {
      allow read, create: if request.auth != null;
      allow update: if request.auth != null
                    && request.resource.data.name == resource.data.name
      allow delete: if false;
    }
  }
}
prescottprue commented 5 years ago

@mattvick Totally a reasonable solution for now, and it would be great to add to the docs.

That said, I do think it makes sense to include this in the api moving forward - that way we could have a way to opt in/out of using profiles for anonymous users.

enkeyz commented 3 years ago

Is anonymous login added yet? Would be nice to have instead of writing you own logic.