2
votes

I'm handling both anonymous and Google accounts using AngularFire2. If a user logs in using a Google account, I'd like to convert their anonymous account to their permanent (Google) account, so they can keep using the app seamlessly.

It seems easy enough using the Firebase API, but I'm not seeing the ability to do this in AngularFire2.

For Firebase, you get the AuthCredential for the new auth provider and then use the link method to convert the account:

var credential = firebase.auth.GoogleAuthProvider.credential(
  googleUser.getAuthResponse().id_token);

auth.currentUser.link(credential).then(function(user) {
  console.log("Anonymous account successfully upgraded", user);
}, function(error) {
  console.log("Error upgrading anonymous account", error);
});

Is this possible in AngularFire2?

3

3 Answers

3
votes

There should be no reason you cannot use the underlying Firebase API, as the Firebase App that's created by AngularFire2 is made available for injection.

You can use the injected app to access any methods of the auth() (or storage()) instances that are not exposed by AngularFire2.

For the purposes of an example, you could inject it into an app component like this:

import { Component, Inject } from "@angular/core";
import { AngularFire, FirebaseApp } from "angularfire2";
import * as firebase from "firebase";

@Component({
  selector: "app",
  template: ...
})
export class AppComponent {

  constructor(
    // Inject AngularFire2:
    private angularFire: AngularFire,
    // Inject the Firebase App instance:
    @Inject(FirebaseApp) private firebaseApp: firebase.app.App
  ) {

    // Perform some sort of login.

    ...

    angularFire.auth.subscribe((state) => {

      // AngularFire2's auth observable will emit when the authentication
      // state changes and if the state is non-null, there will be a
      // current user. At this point, you should be able to do with the
      // injected app what it was you were doing with the SDK.

      if (state) {

        var credential = firebase.auth
          .GoogleAuthProvider
          .credential(googleUser.getAuthResponse().id_token);

        firebaseApp.auth()
          .currentUser
          .link(credential)
          .then((user) => {
            console.log("Anonymous account successfully upgraded", user);
          })
          .catch((error) => {
            console.log("Error upgrading anonymous account", error);
          });
      }
    });
  }
}

You don't have to use the auth observable; you could also put the code into a promise chain using the promise returned by AngularFire2's auth.login method.

As noted in the comments below, the GoogleAuthProvider class is in the firebase.app namespace (not the app instance). Also, as the current user is made available by AngularFire2 in the (confusingly named) auth property of the FirebaseAuthState, you don't need to inject the app instance to do what you want to do with the Google provider. You just need the firebase import:

this.angularFire.auth.login({
  email: "[email protected]",
  password: "password",
})
.then((authState: FirebaseAuthState) => {
  authState.auth.linkWithRedirect(new firebase.auth.GoogleAuthProvider());
});
1
votes

Full example in AngularFire2 v4. It will upgrade an anonymous user to the Google provider, keeping the same auth UID.

import { Component, OnInit } from '@angular/core';
import { AngularFireAuth } from 'angularfire2/auth';
import * as firebase from 'firebase/app';
import { Observable } from 'rxjs/Observable';

@Component({
  selector: 'app-user',
  templateUrl: './user.component.html',
  styleUrls: ['./user.component.scss']
})
export class UserComponent implements OnInit {

  user: Observable<firebase.User>;

  constructor(private afAuth: AngularFireAuth) { }

  ngOnInit() {
    this.user = this.afAuth.authState;
  }

  anonymousLogin() {
    return this.afAuth.auth.signInAnonymously()
  }

  anonymousUpgrade() {
    const provider = new firebase.auth.GoogleAuthProvider()
    firebase.auth().currentUser.linkWithPopup(provider)
  }


}
0
votes

here is a working example;

import * as firebase from 'firebase':


upgradeAnonymous() {

    let credential = new firebase.auth.GoogleAuthProvider();

    firebase.auth().currentUser.linkWithPopup(credential).then(function(user) {
       console.log("Anonymous account successfully upgraded", user);
      }, function(error) {
        console.log("Error upgrading anonymous account", error);
      })
}