'firebase.auth().currentUser is null

I'm trying to retrieve the UID of the current logged-in firebase user in my Angular 4 app. Though, if I'm logging 'firebase.auth().currentUser' to the console I get a 'null'. So 'firebase.auth().currentUser.uid' gives an 'Cannot read property 'uid' of null' error.

According to this article https://firebase.google.com/docs/auth/web/manage-users that would mean that I'm currently not logged in. Though, I am, since I can read data from my database (my rules do not allow unauthenticated users), and the login method did not gave any errors.

I can also see that the user with uid 1 is logged in in the firebase console (.../u/1/project/my-project/authentication/users)

My database rules:

{
  "rules": {
    "users": {
      "$uid": {
        ".write": "$uid === auth.uid",
        ".read": "$uid === auth.uid"
      }
    }
   }
}

Note: I'm not using any of the Firebase login methods. I'm using my php back-end to verify users and generate a custom token for firebase, exactly as described here: https://firebase.google.com/docs/auth/admin/create-custom-tokens.

Angular 4 login code:

constructor(private afAuth: AngularFireAuth) {
    this.login();
}

login() {
    console.log('We are logging in on Firebase :)');
    firebase.auth().signInWithCustomToken(localStorage.getItem('firebase_token')).catch(function (error) {
        console.log(error.message);
        console.log('You are not logged in!');
    });
    this.user = firebase.auth().currentUser;
    console.log(firebase.auth().currentUser);
    console.log(firebase.auth().currentUser.uid);
}

Console output:

chat.service.ts:59 We are logging in on Firebase :)
chat.service.ts:65 null
ChatComponent_Host.html:1 ERROR TypeError: Cannot read property 'uid' of null
    at ChatService.Array.concat.ChatService.login (chat.service.ts:66)
    at new ChatService (chat.service.ts:23)
    at _createClass (core.es5.js:9572)
    at _createProviderInstance$1 (core.es5.js:9544)
    at resolveNgModuleDep (core.es5.js:9529)
    at NgModuleRef_.get (core.es5.js:10615)
    at resolveDep (core.es5.js:11118)
    at createClass (core.es5.js:10971)
    at createDirectiveInstance (core.es5.js:10802)
    at createViewNodes (core.es5.js:12230)
    at createRootView (core.es5.js:12125)
    at callWithDebugContext (core.es5.js:13506)
    at Object.debugCreateRootView [as createRootView] (core.es5.js:12823)
    at ComponentFactory_.create (core.es5.js:9916)
    at ComponentFactoryBoundToModule.create (core.es5.js:3333)


Solution 1:[1]

I think you should modify your code to the following and try again :-

constructor(private afAuth: AngularFireAuth) {
    this.login();
}

login() {
    console.log('We are logging in on Firebase :)');
    firebase.auth().signInWithCustomToken(localStorage.getItem('firebase_token'))
    .then(success=>{
    this.user = firebase.auth().currentUser;
    console.log(firebase.auth().currentUser);
    console.log(firebase.auth().currentUser.uid);
    })
   .catch(function (error) {
        console.log(error.message);
        console.log('You are not logged in!');
    });

}

By using then, you'd make sure that the sign in promise was returned successfully before you access the signed in user object.

Solution 2:[2]

You are using the currentUser variable when firebase still has not loaded data from local. So, in order to know when the currentUser variable is initiated you can check the callback for onAuthStateChanged.

var currentUser;
firebase.auth().onAuthStateChanged(function(user){
    // user holds the reference to currentUser variable.
});

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Rohan Stark
Solution 2 Stefan Falk