Home>

Thank you for browsing.

I would like to use React and Firebase to add user information toFirestoreafter Google authentication if there is no user information yet.

I tried to implement it as follows, but Google authentication itself was done withoutthenafter Firebase being executed, but no user information was added to the database. Hmm. For some reason, the redirect seems to work.

  

Firestore rules

rules_version = '2';
service cloud.firestore {
  match/databases/{database}/documents {
    match/{document = **} {
      allow read, write: if request.time<timestamp.date (2019, 12, 22);
    }
  }
}
  

src/components/Login.js

class Login extends React.Component {
  constructor (props) {
    super (props);
  }
  login = () =>{
    let user;
    const provider = new firebase.auth.GoogleAuthProvider ();
    firebase
      .auth ()
      .signInWithRedirect (provider)
      .then (result =>{
        console.log ("result", result);
        // The result here is not reflected on the console
        user = result.user;
        const userRef = firebase
          .firestore ()
          .collection ("users")
          .doc (user.uid);
        return userRef.get ();
      })
      .then (doc =>{
        if (doc.exists) {
          console.log ("Doc for user" + user.uid + "already exists");
          throw new Error ("Doc for user" + user.uid + "already exists");
        } else {
          return doc.ref.set ({
            uid: user.uid,
            name: user.displayName,
            photoURL: user.photoURL
          });
        }
      })
      .then (() =>{
        this.props.history.push ("/");
      })
      .catch (error =>{
        console.log (error);
        this.props.history.push ("/ errorPage");
      });
  };
  render () {
    if (firebase.auth (). currentUser! == null) {
      return<Redirect to = "/" />;
    }
    return (
      
        <Button variant = "contained" color = "primary" onClick = {this.login}>
          Google Login
        </Button>
      
    );
  }
}
export default withRouter (Login);

Thank you for borrowing your wisdom.

  • Answer # 1

    I can't deny the feeling that it's forcibly, but I writecomponentDidMountat the redirect destination as shown below, and add it if there is no user in session by any chance It was.

    async componentDidMount () {
        firebase.auth (). onAuthStateChanged (user =>{
          if (user) {
            this.onUserIdentify (user);
          } else {
            this.props.history.push ("/");
          }
        });
      }
      onUserIdentify = user =>{
        firebase
          .firestore ()
          .collection ("users")
          .doc (user.uid)
          .get ()
          .then (doc =>{
            if (doc.exists) {
              console.log ("Doc for user" + user.uid + "already exists");
              throw new Error ("Doc for user" + user.uid + "already exists");
            } else {
              return doc.ref.set ({
                uid: user.uid,
                name: user.displayName,
                photoURL: user.photoURL
              });
            }
          })
          .catch (error =>{
            console.log (error);
          });
      };

    Because it's uncomfortable, please let me know if you can add it right after login!

Related articles