Search code examples
angularfirebasegoogle-cloud-firestorefirebase-authenticationangularfire

Angularfire - Only write to Firestore on the first OAuth (Google, facebook) login


packages:

  • "@angular/cdk": "~10.0.0",
  • "@angular/fire": "^6.0.5",
  • "firebase": "^8.0.0",

I have an Angular application with Firebase as a serverless backend solution. Users can register and login through Firebase Auth using their Facebook or Google Accounts. After they successfully login, I store their information (displayName, createdAt, contactEmail) in Firestore.

This is the method I use:

  public async googleLogin(): Promise<void> {
    try {
      const provider = new firebase.auth.GoogleAuthProvider();
      const response = await this.afAuth.signInWithPopup(provider);

      return this.afStore.create(response.user.uid,
        {
          id: response.user.uid,
          contactEmail: response.user.email,
          displayName: response.user.displayName,
          createdAt: this._userDB.createTimestamp()
        }
      );
    } catch (error) {
      return Promise.reject(error);
    }
  }

However, my problem is that every time the user logs in, this function will be called and subsequently previously set fields like displayName, createdAt and contactEmail will be overwritten. I´ve no idea how to check in Firebase Auth if the user is new or just logs in again.


Solution

  • In the credential (your const response variable), you can access to response.additionalUserInfo.isNewUser to know if it is a new user or not. Create the user if true or do nothing otherwise:

      public async googleLogin(): Promise<void> {
        try {
          const provider = new firebase.auth.GoogleAuthProvider();
          const response = await this.afAuth.signInWithPopup(provider);
          // return an empty promise if user is not new
          if (!response.additionalUserInfo.isNewUser) { return Promise.resolve(); }
          return this.afStore.create(response.user.uid,
            {
              id: response.user.uid,
              contactEmail: response.user.email,
              displayName: response.user.displayName,
              createdAt: this._userDB.createTimestamp()
            }
          );
        } catch (error) {
          return Promise.reject(error);
        }
      }