How to store firebase authentication session - javascript

I have a web application made in vue with firebase authentication. The problem here is that I need to login every time I reload the page.

Firebase Authentication by default stores the user's credentials in local storage of the browser, and restores it from there when the page reloads. This requires a call to the server though, which means that if you access Firebase.auth().currentUser immediately as the page loads, it might not be set yet.
To prevent having this problem, use an auth state listener as shown in the first snippet of the documentation on getting the current user.
For v8 and earlier of the SDK that'd be:
firebase.auth().onAuthStateChanged((user) => {
if (user) {
// User is signed in, see docs for a list of available properties
// https://firebase.google.com/docs/reference/js/firebase.User
var uid = user.uid;
// ...
} else {
// User is signed out
// ...
}
});
For v9:
import { getAuth, onAuthStateChanged } from "firebase/auth";
const auth = getAuth();
onAuthStateChanged(auth, (user) => {
if (user) {
// User is signed in, see docs for a list of available properties
// https://firebase.google.com/docs/reference/js/firebase.User
const uid = user.uid;
// ...
} else {
// User is signed out
// ...
}
});

Related

Keep logged in between reloads - Firebase (Sign in with Google)

How do you keep a user logged in with Sign in with Google between reloads?
Here is my login function (Firebase):
const loginWithGoogle = async () => {
try {
const provider = new firebase.auth.GoogleAuthProvider();
const res = await firebase.auth().signInWithPopup(provider);
$user = res.user;
$isLoggedIn = true;
}
catch (error) {
console.log(error);
}
}
Although $isLoggedIn and the $user object save to LocalStorage (I'm using SvelteJS), the user does not actually stay logged in after reloading.
After reloading, admin users are no longer able to write to the database and I get the error firestore: PERMISSION_DENIED: Missing or insufficient permissions.
(Here are my firestore rules)
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read;
allow write: if (request.auth != null && (request.auth.uid == "someAdminID" || request.auth.uid == "otherAdminID"));
}
}
How would I stay logged in after reloading? Or is there some way to automatically log in again if the user had not previously logged out?
On most browser environments Firebase automatically persists the user credentials in local storage, and restores them when the app/page reloads. This requires it to make a call to the server however, a.o. to check if the account was disabled, and thus it isn't completed right away when the page loads.
To react to when the authentication state is restored (or otherwise changes), you'll want to use an auth state listener as shown in the first code snippet in the documentation on getting the currently signed in user:
firebase.auth().onAuthStateChanged((user) => {
if (user) {
// User is signed in, see docs for a list of available properties
// https://firebase.google.com/docs/reference/js/firebase.User
var uid = user.uid;
// ...
// 👈 This is where you can also query the database as the user for the first time
} else {
// User is signed out
// ...
}
});

currentUser not work or not exist in firebase 9

import { getAuth, onAuthStateChanged } from "firebase/auth";
const auth = getAuth();
const user = auth.currentUser;
user return null !!
and this not
onAuthStateChanged(auth, (user) => {
if (user) {
// User is signed in, see docs for a list of available properties
// https://firebase.google.com/docs/reference/js/firebase.User
const uid = user.uid;
console.log(user.email);
// ...
} else {
// User is signed out
// ...
}
});
What you're seeing seems like the expected behavior to me.
When you access auth.currentUser, it gives you the current user when that code runs. Firebase automatically restores the user's credentials when a page loads and this requires a call to the server. This means that when your auth.currentUser runs, that call may not have completed yet, and thus the current user is null.
When on the other hand you use onAuthStateChanged, Firebase only calls your code when it has completed the first check of the user's credentials. So now your code runs after the user has been signed in, and user is no longer null.
This is one of the main reasons it's almost always better to use an auth state listener.
You could use either of these:
this.user$ = authState(auth);
OR
this.user$ = new Observable((observer: any) =>
onAuthStateChanged(auth, observer)
);
OR
this.user$ = user(auth);
and get the Promise version like so:
const user = await this.user$.pipe(take(1)).toPromise();

Firebase email/password authentication in electron

I did firebase authentication with email/password in my electron app, and it works, but only on first page. When I go to second page, I'm no longer signed in. Because I'm new to elecetron.js and firebase as well I used this tutorial:https://www.youtube.com/watch?v=bWS0ocfszmE.
login.js
loginBtn.addEventListener('click', function() {
var emailField = document.getElementById('email').value;
var passwordField = document.getElementById('password').value;
firebase.auth().signInWithEmailAndPassword(emailField, passwordField).then(function() {
document.location.href = 'mainPage.html';
console.log(firebase.auth().currentUser);
}).catch(function(error) {
if (error != null) {
console.log(error.message);
alertify.error(error.message);
return;
}
});
secondpage.js
var firebase = require("firebase/app");
require("firebase/auth");
console.log(firebase.auth().currentUser);
I expected the output in console with user that I signed in, but get null.
The problem is that on each new page Firebase Authentication will check whether the user's sign-in token is still valid. Since this may take some time (and require calling a server), this happens asynchronously. And by the time your console.log(firebase.auth().currentUser) runs, the process hasn't completed yet.
That's why you'll want to use an onAuthStateChanged listener to detect the authentication state of the user:
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
// User is signed in.
} else {
// No user is signed in.
}
});

Firebase Current User Undefined when Web Page is Refreshed

My scenario is simple. I created a Firebase web app and I connect using a Google account. The issue is that I need to log back in every time the page is refreshed, here are the steps :
Initialize Firebase
Signup with Google
Check the current user - it is an authentified Google user
Refresh the page
Initialize Firebase
Check the current user - it is undefined
The code is straightforward:
firebase.initializeApp(config);
var provider = new firebase.auth.GoogleAuthProvider();
firebase.auth().signInWithPopup(provider);
...
public onAuthStateChanged(context: any, user: any) {
if (user) { ...
...
//currentUser is defined
get currentUser(): any {
return firebase.auth().currentUser;
}
Refresh the page
//currentUser is undefined
get currentUser(): any {
return firebase.auth().currentUser;
}
...
if(!currentUser) {
firebase.auth().signOut();
firebase.initializeApp(config);
}
I am aware of options in the persistence of the Firebase sessions but my understanding is that this behavior is not the default. Cf. the doc:
https://firebase.google.com/docs/auth/web/auth-state-persistence
I added this line to my code just in case, it makes no difference:
firebase.auth().setPersistence(firebase.auth.Auth.Persistence.SESSION)
I also checked that the same happens with Anonymous authentication.
Every time you call signInWithPopup(...) it will show a pop up window and ask the user to sig in. For that reason you should only call this method once you detect that the user isn't signed in. The easiest way to do this, is to call it from your onAuthStateChanged callback:
firebase.initializeApp(config);
var provider = new firebase.auth.GoogleAuthProvider();
...
public onAuthStateChanged(context: any, user: any) {
if (user) {
console.log(user);
...
}
else {
firebase.auth().signInWithPopup(provider);
}
...
}

Firebase passing Authentication between web pages

i don't know how to share the authentication between my web. For example, i want to pass authentication to home page after user logged in in login.html.
What is the problem:
After user logged in in login.html, the authentication is created.
//login.html
var user = firebase.auth().currentUser;
if (user) {
// User is signed in.
}
However, i need to change location.href to home.html after user logged in.
//login.html
if (user) {
// User is signed in.
location.href = "home.html";
}
So, what is the solution that keep the authentication when changing web page?
//home.html
if (user) {
//
}else {
// No user is signed in.
}
web/login.html <--> web/home.html
Firebase keeps track of the authentication state between pages by storing the session id in local storage.
The best way to ensure a smooth flow for you users is to monitor the authentication state. From that documentation:
The recommended way to get the current user is by setting an observer on the Auth object:
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
// User is signed in.
} else {
// No user is signed in.
}
});
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.

Categories

Resources