Luke Schlangen
Luke Schlangen

Reputation: 3882

Finding correct Firebase Auth id_token on $onAuthStateChanged

I am currently using Angular 1.5.8, Firebase 3.3.0, and AngularFire 2.0.2. When I call $firebaseAuth.$signInWithPopup, the promise returns with a firebase user that includes firebase.user.idToken, but when I call $onAuthStateChanged, firebase user does not return with a .user property. What is the correct token to use for server authentication from the $onAuthStateChanged function?

I was using the md property, but then it stopped working and switched to a kd property and I realized that not every user has that. Is it the _lat property? It seems to work this way, but I can't seem to find any documentation around it. Or is this not the correct way to be using the token on an Auth State Change? Is there a best practice? Here is the object I have being returned from the promise.

enter image description here

I appologize for the image, but what is strange is that if I JSON.stringify(firebaseUser) and print it, I end up with a completely different object where firebaseUser.stsTokenManager.accessToken would give me the right key, but if I try firebaseUser.stsTokenManager.accessToken it says that stsTokenManager is undefined.

{
  "uid": "XXXXXXXXXXXXXXXXXXXXXXXXXX",
  "displayName": "Luke Schlangen",
  "photoURL": "XXXXXXXXXXXXXXXXXXXXXXXXXX",
  "email": "[email protected]",
  "emailVerified": true,
  "isAnonymous": false,
  "providerData": [
    {
      "uid": "XXXXXXXXXXXXXXXXXXXXXXXXXX",
      "displayName": "Luke Schlangen",
      "photoURL": "XXXXXXXXXXXXXXXXXXXXXXXXXX",
      "email": "[email protected]",
      "providerId": "google.com"
    }
  ],
  "apiKey": "XXXXXXXXXXXXXXXXXXXXXXXXXX",
  "appName": "[DEFAULT]",
  "authDomain": "XXXXXXXXXXXXXXXXXXXXXXXXXX",
  "stsTokenManager": {
    "apiKey": "XXXXXXXXXXXXXXXXXXXXXXXXXX",
    "refreshToken": "XXXXXXXXXXXXXXXXXXXXXXXXXX",
    "accessToken": "XXXXXXXXXXXXXXXXXXXXXXXXXX",
    "expirationTime": XXXXXXXXXXXXXXXXXXXXXXXXXX
  },
  "redirectEventId": null
}

All of the code seems functional now and seems to be working for every user, but I'm wondering, is there a best-practice for this? Should I be using JSON to convert and then selecting the property from that object? Or is _lat the proper way to grab this key?

var app = angular.module("sampleApp", ["firebase"]);
app.controller("SampleCtrl", function($scope, $firebaseArray, 

$firebaseAuth, $http) {
  var auth = $firebaseAuth();

  $scope.logIn = function login(){
    auth.$signInWithPopup("google").then(function(firebaseUser) {
      console.log("Signed in as:", firebaseUser.user.displayName);
    }).catch(function(error) {
      console.log("Authentication failed: ", error);
    });
  };

  auth.$onAuthStateChanged(function(firebaseUser){
    // firebaseUser will be null if not logged in
    if(firebaseUser) {
      // This is where we make our call to our server
      $http({
        method: 'GET',
        url: '/secretData',
        headers: {
          id_token: firebaseUser._lat
        }
      }).then(function(response){
        $scope.secretData = response.data;
      });
    }else{
      console.log('Not logged in.');
      $scope.secretData = "Log in to get some secret data."
    }

  });

  $scope.logOut = function(){
    auth.$signOut().then(function(){
      console.log('Logging the user out!');
    });
  };
});

The full code can be found at github

Upvotes: 19

Views: 9004

Answers (1)

bojeil
bojeil

Reputation: 30838

It is not clear what you are trying to do. Do not access obfuscated internal properties as these will change. You already noticed that. The correct way is to call getToken in the onAuthStateChanged listener:

firebase.auth().onAuthStateChanged(function(user) {
  if (user) {
    user.getIdToken().then(function(idToken) {
      console.log(idToken);
    });
  }
});

Upvotes: 29

Related Questions