'Firebase javascript auth user displaying null even though user is signed in
I followed the Firebase docs for web development and I used the user.updateProfile
method to add a display name to the user's profile. After signing in, I used console.log(user)
and it worked but when I call updateProfile()
, the value of user
is null. Any solutions?
Here is the relevant code:
var button = document.getElementById("profile-button");
var username = document.getElementById("username-Box").value;
var user = firebase.auth().currentUser;
auth.onAuthStateChanged(user =>{
console.log(user);
})
function updateProfile(){
if (user != null){
user.updateProfile({
displayName : username
}).then(user => {
console.log("Updated Successfully");
window.location.href="chatpage.html";
}).catch(err =>{
console.log(err);
window.alert(err);
});
}else if(user == null){
console.log("No user signed in");
}
}
Solution 1:[1]
You need to wait for onAuthStateChanged
to fire before assigning the user
variable, otherwise the Auth object may be in an intermediate state. This is documented:
By using an observer, you ensure that the Auth object isn't in an intermediate state—such as initialization—when you get the current user. When you use signInWithRedirect, the onAuthStateChanged observer waits until getRedirectResult resolves before triggering.
You can also get the currently signed-in user by using the currentUser property. If a user isn't signed in, currentUser is null:
It's worth explicitly pointing out that the user
variable you console.log
in onAuthStateChanged
is not the same user
variable that's used in your updateProfile
method. While the user maybe "logged in" when onAuthStateChanged
fires, they are likely not logged in when you set your outer user
variable. Therein lies your problem.
It's not clear from your code where updateProfile
is called, but Peter Haddad's answer is likely the solution I would implement. However, note that with the code snippet supplied in that answer you'll also need to change your updateProfile
method to accept a user
parameter. Another approach would be to assign the user
variable inside of onAuthStateChanged
.
let user;
auth.onAuthStateChanged(u => user = u);
With that approach your updateProfile
method should work as is. Just keep in mind that you may have a race condition depending on when you call updateProfile
.
Solution 2:[2]
Since console.log(user)
is returning the correct user, then inside the authstatechanged
call the updateProfile
:
auth.onAuthStateChanged(user =>{
console.log(user);
updateProfile(user);
})
Solution 3:[3]
Based on your snippet, I am assuming that updateProfile()
is your onClick
/onSubmit
event handler for clicking your "update profile" button.
Because of this, your user is likely to have logged in by the time they press the button and therefore it is safe to use firebase.auth().currentUser
in your event handler rather than maintain a user
object in the global scope.
var eleButton = document.getElementById("profile-button");
var eleUsername = document.getElementById("username-Box");
function updateProfile() {
let user = firebase.auth().currentUser;
if (!user) {
alert('Please log in before clicking update profile!')
return;
}
// get current value of '#username-Box'
let username = eleUsername.value.trim();
if (!username) {
alert('Please enter a valid username!')
return;
}
user.updateProfile({
displayName : username
}).then(user => {
console.log("Updated Successfully");
window.location.href="chatpage.html";
}).catch(err =>{
console.log(err);
window.alert(err);
});
}
In your original code, you had the following:
var user = firebase.auth().currentUser; // <-- global-scope variable
auth.onAuthStateChanged(user =>{ // <-- function-scope variable
console.log(user);
})
When onAuthStateChanged
fires, it does log the value of user
, but it sets and logs it's own version of user
, not the user
variable in the global-scope.
If you wanted to update the global-scope version, you need to rename the variable used in your onAuthStateChanged
handler so that it doesn't shadow the user
global-scope variable.
var user = firebase.auth().currentUser; // <-- global-scope variable
auth.onAuthStateChanged(_user =>{ // <-- function-scope variable
user = _user;
console.log(user);
})
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 | |
Solution 2 | Peter Haddad |
Solution 3 | samthecodingman |