k10a
k10a

Reputation: 1087

Can't set user data after firebase auuthentication

I'm working on a react app on firebase. The issue that fire store doesn't set up userdata after fire authentication although it's been successfully authenticated on Google. Please help me if you have some clues to solve that. And I can't get error texts here.

  login = () => {
    const provider = new firebase.auth.GoogleAuthProvider();
    firebase
      .auth()
      .signInWithRedirect(provider)
      .then(result => {
        const user = result.user;
        const userRef = firebase
          .firestore()
          .collection("users")
          .doc(user.uid);

        userRef.get().then(function(doc) {
          if (doc.exists) {
            console.log("User data:", doc.data());
          } else {
            // doc.data() will be undefined in this case
            userRef.set({
              uid: user.uid,
              name: user.displayName,
              photoURL: user.photoURL
            });
          }
        });
      });

    this.props.history.push("/");
  };

Additional

'user' is not defined.
'userRef' is not defined

I have tried the code. But user and userRef could not be defined here:

    if (doc.exists) {
      console.log("Doc for user " + user.uid + " already exists");
      throw new Error("Doc for user " + user.uid + " already exists");
    } else {
      return userRef.set({
        uid: user.uid,
        name: user.displayName,
        photoURL: user.photoURL
      });
    }

Additional 2

I don't know why but that would not work then on Firebase Authentication.

login = () => {
  let user;
  const provider = new firebase.auth.GoogleAuthProvider();
  firebase
    .auth()
    .signInWithRedirect(provider)
    .then(result => {
      console.log("result", result);
      // result has been skipped

Upvotes: 0

Views: 251

Answers (1)

Renaud Tarnec
Renaud Tarnec

Reputation: 83093

Actually, the signInWithRedirect() method returns a promise with no return value (i.e. Promise<void>). Therefore doing

    firebase
      .auth()
      .signInWithRedirect(provider)
      .then(result => {...});

will not work.

You need to use the getRedirectResult() method, as explained in the doc:

Authenticates a Firebase client using a full-page redirect flow. To handle the results and errors for this operation, refer to firebase.auth.Auth.getRedirectResult.

Therefore, in your login function, you should just have two lines:

  login = () => {
    const provider = new firebase.auth.GoogleAuthProvider();
    firebase
      .auth()
      .signInWithRedirect(provider);
  }

And somewhere else in your code (I don't know exactly where as I don't know reactjs...) you need to have the following code (note how the different Promises are chained):

    let user;

    firebase
    .auth()
    .getRedirectResult()
    .then(result => {
        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');
      });

Note that in case several users are able to sign-in with the same Google Account, you may need to use a Transaction when checking the non-existence of the doc at userRef.

Upvotes: 2

Related Questions