Keep user after redirect with firebase - javascript

Im currently working on a side project with firebase on web and it uses user auth. I have the user logging in and then creating a game room which redirects to a separate page for the game "room". After the page redirects though i cannot pull any of the users data and the only way that im doing it is by re initializing firebase and using
auth.onAuthStateChanged(function(user) {
if (user && user != null) {
uid = user.uid;
email = user.email;
currUser = user;
} else {
//user isnt logged in
window.location.href = 'index.html';
}
There seems to probably be an easier way to do this but i cant seem to get it working and this way also messes up sections of my other code.

Attaching an onAuthStateChanged callback is the idiomatic way to get the user.
You can also get the user with firebase.auth().currentUser. But if a token refresh is required, you may in that case mis-detect that there is no user. That why an onAuthStateChanged callback is recommended.
See the Firebase documentation on getting the current user.

Related

firebase - check if an user is already registered in database

I have a firebase app that is running on mobile devices and now I need to create the web version of it.
At the moment I have integrated firebase ui to give to users the ability to login. Since I need to show a wizard if the user isn't already registered, how I can check if user exists in the database so I can decide if show the wizard or not and then add it to the database?
It sounds like you're looking for the fetchSignInMethodsForEmail method, which returns the list of providers with which a specified email address has previously been signed in to Firebase.
The typical flow is:
Get the email address of the user
Call fetchSignInMethodsForEmail to get a list of providers
If the list is empty, go to your account creation flow
If the list has a single value, show the sign in screen for that provider
If the list has multiple values, show a screen where the user can pick from those providers
I consider you are using firebase auth and firestore, but this is the logic
firebase.auth().onAuthStateChanged(async (user)=> {
if (user == null){
//the user is not signed in, navigate to login screen
}else{
//the user is signed in, try to check if he exists in the database or register him
//let say you are using firestore roo
let user_ = await firebase.app().auth().currentUser
firebase.firestore().collection("collections_of_users").doc(user_.uid).get().then(snap =>{
if(snap.exists){
//the user exists
}else{
//register him, and before make sure his email is verified by checking if emailVerified === true
firebase.firestore().collection("collections_of_users").doc(user_.uid).set({user_mail: user_.email, user_name: "xxx"})
}
})
}
});

Getting Uncaught TypeError in Firebase Auth get current user email

I am trying to get the email of the currently signed in user in my Firebase app, but it keeps giving me an error.
This is my code for getting the current user email:
user_email = firebase.auth().currentUser.email
The error that I get is:
Error Image
It looks like firebase.auth().currentUser is null at the time when your firebase.auth().currentUser.email runs. This is quite common, as Firebase refreshes the user's authentication state when the page loads, and this requires it to make an asynchronous call to the server.
For this reason, you should not assume there is a user signed in. You should either put a check around your current code:
if (firebase.auth().currentUser) {
user_email = firebase.auth().currentUser.email
}
Or (and often better) you should use a so-called auth state listener, to have your code automatically respond to changes in the user's authentication state. From the Firebase documentation on getting the currently signed-in user, 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;
user_email = firebase.auth().currentUser.email;
// TODO: execute code that needs `user_email`
} else {
// User is signed out
// ...
}
});

Firebase initialize app lose Current User

I have a web application using html-js-css and a flask server.
My web app is a multi-pages app which apparently means that I have to Initialize firebase for each page in which i want to use it -.-
The problem is that every time I initialize firebase app, I lose the current user so while in my main page, after log-in, if I write:
const USER = firebase.auth().currentUser;
console.log(USER.uid);
I get my user ID, as soon as I move to another page and repeat the above code, I get the error:
TypeError: USER is null
Is there a way to either:
avoid Initializing the firebase-app at avery page
keep the CurrentUser (even storing it securely somewhere)
Thank you
Workaround:
I got this workaround working before Frank answer which is probably the best way to proceed. Instead I just stored the user id in an encrypted variable accessible to all pages.
Since the main.html page is always loaded, I store/removed the variable in a onAuthStateChanged listener there so as soon as the user is logged out, that variable is removed:
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
cached_uid = JSON.stringify(user.uid);
cached_uid = btoa(cached_uid);
localStorage.setItem('_uid',cached_uid);
} else {
localStorage.removeItem('_uid');
}
});
then on the other pages:
function loadUID(){
var uid = localStorage.getItem('_uid');
if (!uid) return false;
uid = atob(uid);
uid = JSON.parse(uid);
return uid
}
I followed this to find this solution:
How to send variables from one file to another in Javascript?
You will need to initialize the Firebase app on each page, but that is supposed to be a fairly cheap operation.
To pick up the user on the new page, Firebase runs a check against the server to ensure the user token is still valid. Since this code calls a server, its result likely isn't available yet when your firebase.auth().currentUser runs.
To solve this, run the code that requires a user in a so-called auth state change listener:
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
// User is signed in.
} else {
// No user is signed in.
}
});
Also see the Firebase documentation on getting the currently signed in user.

Keep user logged in in app even after the app closed using Async Storage

I am trying to maintain a user as logged in, in an app even after the app closed, which means the user will no longer need to re-enter his/her userID and password again everytime he/she opens the app.
I want to achieve this using AsyncStorage (other than redux), my question is: is it possible to do so using AsyncStorage? I found sources online on how to persist data using Async but U could not connect those with what I wanted to do.
You should do it this way:
User opens the app, may be do this in you splash screen's didMount i prefer these kind of things to be done before hand in the splashsreen only. Check a flag in AsyncStorage say isLoggedIn if thats true, fetch
user credentials from the AsyncStorage and fed them to your login
request and the rest of the app flow continues.
If isLoggedIn is false (or null), show login screen to the user and upon successful login, save the credentials to AsyncStorage and on success must save the isLoggedIn flag to true and rest of the app flow continues.
For point 1, the code should look like:
AsyncStorage.getItem('isLoggedIn').then((value) => {
if(value && value === 'YES') {
//hit login api using the saved credentials and take user inside the application.
} else {
//Take user to login page and progress with point 2.
}
});
and below is the code that should work for point 2 upon success of login.
const encrypted_username = myFancyEncrptionFunction(username);
const encrypted_password = myFancyEncrptionFunction(username);
AsyncStorage.setItem('username', encrypted_username).then(()=>{
AsyncStorage.setItem('password', encrypted_username).then(()=>{
AsyncStorage.setItem('isLoggedIn', 'YES');
});
});
Its totally upto you how you want your user's credentials to be saved in AsyncStorage i.e. with or without encryption. But its always recommended to keep such things encrypted.

How to handle user information using firebase simple login for facebook

I am building a webpage using AngularJS and Firebase. I want to use facebook login to connect information on the webpage with the user. Firebase has a version of simple login which I guess is supposed to simplify the login process.
My problem is that I want to access information about the logged in user in a lot of places on my webpage but I can't find a good way to do it.
This is how I started out:
var userInfo = null;
var ref = new Firebase('https://<yourfirebase>.firebaseIO.com/');
var auth = new FirebaseSimpleLogin(ref, function(error, user) {
if(error)
alert("You are not logged in");
else if(user)
{
//store userinfo in variable
userInfo = user;
}
else
//user logged out
});
//do something with userInfo
alert(userInfo.name);
My first thought was to run this at the top of my page and then use the info about the user. The problem is that the code using userInfo (as in e.g. the alert) will always run before the userInfo variable has been filled and userInfo will return undefined/null.
I then proceeded to always create a new firebasesimplelogin object when i want to retrieve user data. Which of course isn't very good. Especially since every created FirebaseSimpleLogin object will be called again whenever another is called or a user logs out, for example.
So my question is, how do I use FirebaseSimpleLogin to handle and use my user information in the best way?
I would have liked some function to getUserInfo() or check isLoggedIn() for example. How do you do this properly?
You can take a look at this example for thinkster. It's based on using simple login with userid/password. http://www.thinkster.io/angularjs/4DYrJRxTyT/7-creating-your-own-user-data-using-firebase.
You can create a function like getLoggedinUser that runs in $rootScope that will allow you to find the user throughout the application.
UPDATE:
Around the middle of October 2014, firebase made some big changes. This method might still work, but it's better to take advantage of the newer version of firebase, specifically getauth and onauth. These methods will allow you to do the same thing without running on the rootScope. https://www.firebase.com/docs/web/guide/user-auth.html#section-login
Please make a constant to use it everywhere in your App like that
.constant('facebookUrl', 'https://rjrestaurantapp.firebaseio.com');
Then in the controller inject this constant "facebookUrl & "$state" as shown below...
.controller('loginCtrl', function($scope,facebookUrl,$state){
and then you only need to give name of the state where you want to redirect after facebook authentication..
var ref = new Firebase(facebookUrl);
$scope.fbLogin = function () {
ref.authWithOAuthPopup("facebook", function(error, authData) {
if (error) {
console.log("Login Failed!", error);
} else {
console.log("Authenticated successfully with payload:", authData);
$state.go('restaurant');
}
})
}})
You can see the information in authData object after successfull authentication using facebook ....
please read this doc carefully https://www.firebase.com/docs/web/guide/login/facebook.html
The above is the example of simple login using firebase and for retrieving data for each logged in user, you have to store user information at the time of signin as you know that firebase makes every child with a unique ID .. then you only need to use the offline features of firebase that will find which user is offline and according to that remove the node with the same ID which one is offline, you can find examples in the MANAGING PRESENCE section of the below link ..
https://www.firebase.com/docs/web/guide/offline-capabilities.html

Categories