Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does firebase' linkWithPopup() not set the user `photoUrl` in firebase?

I'm working on implementing converting anonymous users to permanent users using GitHub auth provider.

The idea is that in my app, users are always automatically authenticated as anonymous users. Then, when they click the "Sign in with GitHub" button, basically what happens is that my app first tries to link that anonymous user to the GitHub credentials (which is basically a signin at the same time), but if the linking fails because the user already exists (e.g. has been linked before), it falls back to a normal sign in using GitHub.

I use firebase' APIs linkWithPopup(provider) and signInWithPopup(provider). Both methods return a promise that resolves with the authenticated GitHub user which is great! However, it turns out that the user object that I get from linkWithPopup() does not have the photoUrl property set. It's always null.

When I signInWithPopup() straight away, without even trying to link, I also get a promise resolved with the user object and this one does have the photoUrl set. So it looks like that there's a bug in linkWithPopUp().

Is this a known issue, or is this expected behaviour?

My code looks like this:

linkOrSignInWithGitHub(): Observable<User> {
    let linkPromise = firebase.auth()
                              .currentUser
                              .linkWithPopup(new firebase.auth.GithubAuthProvider())
                              .then(result => result.user);

    // If a user has been permanentely linked/authenticated already and tries
    // to link again, firebase will throw an error. That's when we know that
    // user credentials do already exist and we can simply sign in using GitHub.
    return Observable.fromPromise(<Promise<any>>linkPromise).catch(error => this.signInWithGitHub());
  }

And signInWithGitHub() looks like this:

signInWithGitHub(): Observable<User> {
  let loginPromise = firebase.auth()
                              .signInWithPopup(new firebase.auth.GithubAuthProvider())
                              .then(result => result.user);

  return Observable.fromPromise(<Promise<any>>loginPromise);
}

So again, the code in itself works perfectly fine, it's just that I don't get the users photoURL when using linkWithPopup().

like image 705
Pascal Precht Avatar asked Mar 13 '17 14:03

Pascal Precht


People also ask

How do I detect if a user is already logged in Firebase?

To detect if a user is already logged in Firebase with JavaScript, we can call the onAuthStateChanged method. firebase. auth(). onAuthStateChanged((user) => { if (user) { // ... } else { // ... } });

What does Firebase auth () CurrentUser return?

If a user isn't signed in, CurrentUser returns null. Note: CurrentUser might also return null because the auth object has not finished initializing.

How do I refresh my Firebase token?

Every time a user signs in, the user credentials are sent to the Firebase Authentication backend and exchanged for a Firebase ID token (a JWT) and refresh token. Firebase ID tokens are short lived and last for an hour; the refresh token can be used to retrieve new ID tokens.


Video Answer


1 Answers

linkWithPopup does not modify the existing top level attributes (currentUser.email, currentUser.displayName, currentUser.photoURL, etc). It will only add a new providerData object in currentUser.providerData with the corresponding providerData you linked with. The top level data is set on sign up as you already notice.

You can update the top level data using that provider's data manually after linkWithPopup resolves. currentUser.updateProfile({ photoURL: currentUser.providerData[indexOfGitHub].photoURL }

like image 72
bojeil Avatar answered Sep 30 '22 06:09

bojeil