firebase.auth().currentUser is null
Asked Answered
S

2

10

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)
Swearword answered 3/7, 2017 at 13:39 Comment(0)
S
0

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.

Siegler answered 3/7, 2017 at 13:57 Comment(3)
Thanks! I'm relatively new to Angular 4 and did not really thought about this. Thanks for your quick and clear answer!Swearword
No problem! I'm glad that I could help.Siegler
In term of security, is it OK to store token at the client?Stacte
G
10

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.
});
Godart answered 26/8, 2017 at 20:50 Comment(0)
S
0

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.

Siegler answered 3/7, 2017 at 13:57 Comment(3)
Thanks! I'm relatively new to Angular 4 and did not really thought about this. Thanks for your quick and clear answer!Swearword
No problem! I'm glad that I could help.Siegler
In term of security, is it OK to store token at the client?Stacte

© 2022 - 2024 — McMap. All rights reserved.