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.
}
});
Related
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
// ...
}
});
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
// ...
}
});
Firebase auth does not persist logged in user and everytime I refresh or reopen app I have to sign in again.
I have tried setting persistence to local and the callback does verify its set but the persistence is still no working
For setting persistence I am using...
//set auth persistence
firebase.auth().setPersistence(firebase.auth.Auth.Persistence.LOCAL)
.then(function() {
console.log("successfully set the persistence");
})
.catch(function(error){
console.log("failed to ser persistence: " + error.message)
});
.
.
.
For signing in I am using this code
firebase.auth().signInWithEmailAndPassword(email, password)
.then((user) =>{
this.checkAccountStatus(user.uid, user.email);
})
.catch(function(error) {
// Handle Errors here.
var errorCode = error.code;
var errorMessage = error.message;
console.log(errorMessage)
// ...
});
And here is the code I am using to check login status...
if (firebase.auth().currentUser) {
const currentUser = firebase.auth().currentUser;
console.log("Signed in username" + currentUser.displayName);
this.props.navigation.navigate('AppTab');
}else{
console.log("no user signed in");
this.props.navigation.navigate('AuthTab');
}
if there anything I am not doing right
You don't need to set persistence. Firebase handles it for you by default. You just need to call this function to check whether user is logged or not:
firebase.auth().onAuthStateChanged((user) => {
if (user) {
console.log('user is logged');
}
});
This will not be triggered only if user has sign out or cleaned app data.
You can find more details in the official docs: https://firebase.google.com/docs/auth/web/manage-users
Hope it helps.
Make sure you do not restrict the 'Token Service API' in the console, with the API key you are using. I did not add the service to my key, and it logged me out every 3-4 hours, even with the right code suggested above.
Firebase now recommends to use firestore instead of realtime-database and it manages offline persistence by default. It is clear in its documentation here
You just need to access the user through this code:
if (auth().currentUser !== null) {
console.log('User is logged in');
console.log(auth().currentUser.email);
props.navigation.navigate('Home');
} else {
props.navigation.navigate('Login');
}
This code will prop you to home screen if user is logged-in, even when you close the app. To clear the user's credentials, you manually need to sign-out the user using this code.
try {
auth()
.signOut()
.then(props.navigation.navigate('Login'));
} catch (error) {
Alert.alert('Error', error.toString());
}
You can also check this simple app (used react hooks in it) for further assistance.
How can I redirect to a different webpage after the user has signed in?
Currently when a user logs in, data gets retrieved however, it doesn't redirect the user to a different website.
I know I should use 'getRedirectResult', but can someone show me how to use it and how it redirect the user to a different webpage, maintaining the retrieved user data.
My javascript work:
function toggleSignIn() {
if (!firebase.auth().currentUser) {
// [START createprovider]
var provider = new firebase.auth.GoogleAuthProvider();
// [END createprovider]
// [START addscopes]
provider.addScope('https://www.googleapis.com/auth/plus.login');
// [END addscopes]
// [START signin]
firebase.auth().signInWithPopup(provider).then(function(result) {
// This gives you a Google Access Token. You can use it to access the Google API.
var token = result.credential.accessToken;
// The signed-in user info.
var user = result.user;
// [START_EXCLUDE]
document.getElementById('quickstart-oauthtoken').textContent = token;
// [END_EXCLUDE]
}).catch(function(error) {
// Handle Errors here.
var errorCode = error.code;
var errorMessage = error.message;
// The email of the user's account used.
var email = error.email;
// The firebase.auth.AuthCredential type that was used.
var credential = error.credential;
// [START_EXCLUDE]
if (errorCode === 'auth/account-exists-with-different-credential') {
alert("You have already signed up with a different auth provider for that email.");
// If you are using multiple auth providers on your app you should handle linking
// the user's accounts here.
}
else if (errorCode === 'auth/auth-domain-config-required') {
alert("An auth domain configuration is required");
}
else if (errorCode === 'auth/cancelled-popup-request') {
alert("Popup Google sign in was canceled");
}
else if (errorCode === 'auth/operation-not-allowed') {
alert("Operation is not allowed");
}
else if (errorCode === 'auth/operation-not-supported-in-this-environment') {
alert("Operation is not supported in this environment");
}
else if (errorCode === 'auth/popup-blocked') {
alert("Sign in popup got blocked");
}
else if (errorCode === 'auth/popup-closed-by-user') {
alert("Google sign in popup got cancelled");
}
else if (errorCode === 'auth/unauthorized-domain') {
alert("Unauthorized domain");
}
else {
console.error(error);
}
// [END_EXCLUDE]
});
// [END signin]
} else {
// [START signout]
firebase.auth().signOut();
// [END signout]
}
// [START_EXCLUDE]
document.getElementById('quickstart-sign-ing').disabled = false;
// [END_EXCLUDE]
}
Get the email and password from user and then pass the values to signInWithEmailAndPassword, if some error occurs it will print the message, if not Firebase will successfully sign the user in.
firebase.auth().signInWithEmailAndPassword(email, password).catch(function(error) {
// Handle Errors here.
var errorCode = error.code;
console.log(error.Message);
});
You also need a listener that handles login and logout status. This is where you can redirect users if they have successfully logged in.
To handle login and logout, always use onAuthStateChanged()
//Handle Account Status
firebase.auth().onAuthStateChanged(user => {
if(user) {
window.location = 'home.html'; //After successful login, user will be redirected to home.html
}
});
The moment someone logins, user will be populated with user details and you can use it to redirect to another page.
You just need to add two redirects inside initApp() to make this happen. I’m referring to the quickstart git repo https://github.com/firebase/quickstart-js/blob/master/auth/email.html, as I came here via the duplicate question Redirecting to a page after Firebase login - Javascript
1) on line 163, add the page you want logged-in users to be redirected to:
162 //User is signed in.
163 window.location = ‘loggedIn.html’;
164 var displayName = user.displayName;
2) on line 180 (now 181 because of the add above), add a redirect back to the login page:
180 // User is signed out.
181 window.location = ‘index.html’;
182 // [START_EXLUDE]
You need to add the entire script to both the index and the logged in pages - so everything (including the script tags) between lines 37 and 201 from the original git repo (but with the two redirect additions above).
Now, if you try to go directly to loggedIn.html without logging in, the initApp function will check if you are logged in, see that you aren’t, and redirect you to the login page.
The only issue is you get a quick flash of the logged content before the redirect, so to get around this you could set the body of this page to be hidden, and have a script that runs if the user is logged in that removes the hidden class.
Lastly, you’ll want to add a redirect inside the toggleSignIn function, on line 46 of the original repo:
45 firebase.auth().signOut();
46 window.location = ‘index.html’;
47 // [END signout]
If you're building a single-page style application, you likely don't need to redirect. Instead you would just change your application state when the user logs in. If you do want to change the URL, however, you can simply set the window location using JavaScript in your success callback. For example:
window.location = '/logged_in.html'
Note that on the new page you will need to listen for the auth state as well:
firebase.auth().onAuthStateChanged(function(currentUser) {
if (currentUser) {
// the user is logged in, you can bootstrap functionality now
}
});
In general Firebase applications on the web will work better if you don't structure your app to need hard page loads in between state transitions. Everything can and ideally should be managed using JavaScript without requiring an extra page load.
You can assign to location in the JavaScript, e.g. location = 'https://google.com' or location = '/logged-in-page.html'.
How can I redirect to a different webpage after the user has signed in?
Currently when a user logs in, data gets retrieved however, it doesn't redirect the user to a different website.
I know I should use 'getRedirectResult', but can someone show me how to use it and how it redirect the user to a different webpage, maintaining the retrieved user data.
My javascript work:
function toggleSignIn() {
if (!firebase.auth().currentUser) {
// [START createprovider]
var provider = new firebase.auth.GoogleAuthProvider();
// [END createprovider]
// [START addscopes]
provider.addScope('https://www.googleapis.com/auth/plus.login');
// [END addscopes]
// [START signin]
firebase.auth().signInWithPopup(provider).then(function(result) {
// This gives you a Google Access Token. You can use it to access the Google API.
var token = result.credential.accessToken;
// The signed-in user info.
var user = result.user;
// [START_EXCLUDE]
document.getElementById('quickstart-oauthtoken').textContent = token;
// [END_EXCLUDE]
}).catch(function(error) {
// Handle Errors here.
var errorCode = error.code;
var errorMessage = error.message;
// The email of the user's account used.
var email = error.email;
// The firebase.auth.AuthCredential type that was used.
var credential = error.credential;
// [START_EXCLUDE]
if (errorCode === 'auth/account-exists-with-different-credential') {
alert("You have already signed up with a different auth provider for that email.");
// If you are using multiple auth providers on your app you should handle linking
// the user's accounts here.
}
else if (errorCode === 'auth/auth-domain-config-required') {
alert("An auth domain configuration is required");
}
else if (errorCode === 'auth/cancelled-popup-request') {
alert("Popup Google sign in was canceled");
}
else if (errorCode === 'auth/operation-not-allowed') {
alert("Operation is not allowed");
}
else if (errorCode === 'auth/operation-not-supported-in-this-environment') {
alert("Operation is not supported in this environment");
}
else if (errorCode === 'auth/popup-blocked') {
alert("Sign in popup got blocked");
}
else if (errorCode === 'auth/popup-closed-by-user') {
alert("Google sign in popup got cancelled");
}
else if (errorCode === 'auth/unauthorized-domain') {
alert("Unauthorized domain");
}
else {
console.error(error);
}
// [END_EXCLUDE]
});
// [END signin]
} else {
// [START signout]
firebase.auth().signOut();
// [END signout]
}
// [START_EXCLUDE]
document.getElementById('quickstart-sign-ing').disabled = false;
// [END_EXCLUDE]
}
Get the email and password from user and then pass the values to signInWithEmailAndPassword, if some error occurs it will print the message, if not Firebase will successfully sign the user in.
firebase.auth().signInWithEmailAndPassword(email, password).catch(function(error) {
// Handle Errors here.
var errorCode = error.code;
console.log(error.Message);
});
You also need a listener that handles login and logout status. This is where you can redirect users if they have successfully logged in.
To handle login and logout, always use onAuthStateChanged()
//Handle Account Status
firebase.auth().onAuthStateChanged(user => {
if(user) {
window.location = 'home.html'; //After successful login, user will be redirected to home.html
}
});
The moment someone logins, user will be populated with user details and you can use it to redirect to another page.
You just need to add two redirects inside initApp() to make this happen. I’m referring to the quickstart git repo https://github.com/firebase/quickstart-js/blob/master/auth/email.html, as I came here via the duplicate question Redirecting to a page after Firebase login - Javascript
1) on line 163, add the page you want logged-in users to be redirected to:
162 //User is signed in.
163 window.location = ‘loggedIn.html’;
164 var displayName = user.displayName;
2) on line 180 (now 181 because of the add above), add a redirect back to the login page:
180 // User is signed out.
181 window.location = ‘index.html’;
182 // [START_EXLUDE]
You need to add the entire script to both the index and the logged in pages - so everything (including the script tags) between lines 37 and 201 from the original git repo (but with the two redirect additions above).
Now, if you try to go directly to loggedIn.html without logging in, the initApp function will check if you are logged in, see that you aren’t, and redirect you to the login page.
The only issue is you get a quick flash of the logged content before the redirect, so to get around this you could set the body of this page to be hidden, and have a script that runs if the user is logged in that removes the hidden class.
Lastly, you’ll want to add a redirect inside the toggleSignIn function, on line 46 of the original repo:
45 firebase.auth().signOut();
46 window.location = ‘index.html’;
47 // [END signout]
If you're building a single-page style application, you likely don't need to redirect. Instead you would just change your application state when the user logs in. If you do want to change the URL, however, you can simply set the window location using JavaScript in your success callback. For example:
window.location = '/logged_in.html'
Note that on the new page you will need to listen for the auth state as well:
firebase.auth().onAuthStateChanged(function(currentUser) {
if (currentUser) {
// the user is logged in, you can bootstrap functionality now
}
});
In general Firebase applications on the web will work better if you don't structure your app to need hard page loads in between state transitions. Everything can and ideally should be managed using JavaScript without requiring an extra page load.
You can assign to location in the JavaScript, e.g. location = 'https://google.com' or location = '/logged-in-page.html'.