AngularFire: Resuming an anonymous session - javascript

From the Simple Web Login docs, it claims you can resume a session by doing the following:
var auth = new FirebaseSimpleLogin(chatRef, function(error, user) {
...
});
Is there an equivalent for AngularFire?
The $firebaseSimpleLogin constructor takes a firebase reference as its only parameter..
Specifically, what I'm trying to do is login once anonymously and resume that login on a full page refresh. Is that achievable?

Whether or not your auth session is preserved is determined by the parameters you pass into the login method. Whether you use FirebaseSimpleLogin or $firebaseSimpleLogin is irrelevant here.
var auth = $firebaseSimpleLogin(ref);
$rootScope.$on('$firebaseSimpleLogin:login', function(user) {
console.log('logged in', user.uid);
});
// automagically logs in the next time you call $firebaseSimpleLogin() after page refresh
auth.$login('anonymous', { rememberMe: true });
// does not automagically log in
auth.$login('anonymous');
UPDATE As of Angular 1.x and Firebase 2.x this syntax and behavior has changed.
From the remember attribute in Firebase docs:
If not specified - or set to default - sessions are persisted for as
long as you have configured in the Login & Auth tab of your App
Dashboard. To limit persistence to the lifetime of the current window,
set this to sessionOnly. A value of none will not persist
authentication data at all and will end authentication as soon as the
page is closed.
var auth = $firebaseAuth(ref);
$firebaseAuth.$onAuth(function(user) {
console.log('logged ' + (user? 'in' : 'out'), user && user.uid);
});
// stays logged in for length specified in the app dashboard
auth.$authAnonymously();
// stays logged in until the browser closes
auth.$authAnonymously({ remember: 'sessionOnly' });
// does not stay logged in on page refresh
auth.$authAnonymously({ remember: 'none' });

Related

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.

Create accounts in Firebase Auth from custom admin website while I'm logged in

I'm doing a web application using Angular 8 and AngularFire.
On my custom website, a user with the admin privilege, can create accounts for other people.
To do this, I have read that I need to:
Create a second auth reference and use that to create users.
Reason: if we use our default auth reference, when the createUserWithEmailAndPassword() method creates the new user, the
user is signed in automatically, overriding our current session (the
logged in user on our custom website).
I have tried:
async createUserWithEmailAndPassword(email: string, password: string): Promise<string> {
// 1. A new auth session
let secondaryApp = firebase.initializeApp(environment.firebaseConfig, 'Secondary');
// 2. Create the account
const user = await secondaryApp.auth().createUserWithEmailAndPassword(email, password);
// 3. Sign out the user created
await secondaryApp.auth().signOut();
// 4. Make the auth session null to ensure that it's deleted
secondaryApp = null;
if (user.user.uid) {
// User created
return Promise.resolve(user.user.uid);
} else {
// Error
return Promise.reject();
}
}
Error received (happens when I call the method a second time):
FirebaseError: Firebase: Firebase App named 'Secondary' already exists
(app/duplicate-app).
My thoughts/steps were:
Create a new auth session.
Create the user.
Sign out the user created.
Delete the auth session created.
All clear and ready to create a new account in any moment.
What I'm doing wrong?
My goal is to be able to create accounts while I'm logged in on my custom website.
An educated guess is that you get that error message the second time you call your own createUserWithEmailAndPassword method. The reason for that is that you've already created an app named Secondary on the previous call, and didn't remove that app.
The easiest solution is to check if the Secondary app already exists before creating it.
let secondaryApp = firebase.app("Secondary");
if (!secondaryApp) {
secondaryApp = firebase.initializeApp(environment.firebaseConfig, 'Secondary');
}

Firebase: Store anonymous authentication in cookies

I am developing multi page application, that uses firebase as a back-end.
On every page after firebase initialization I have the following code:
firebase.auth().signInAnonymously().catch(...);
firebase.auth().onAuthStateChanged(function(user)
{
if (user) {
// ...
} else {
// User is signed out.
// ...
}
// ...
});
which sign in every visitor anonymously.
The problem is, when user navigates to another page of my application or opens it in a new tab, or just refreshes the current page - new anonymous user is generated.
I can use client side cookies to store anonymous user id, but how can I later (after page refresh) use that stored anonymous user id, to sign in user with that id?
It was my mistake,
firebase store anonymous user authorization in local storage by default.
My code sample should be rewritten this way to work properly:
firebase.auth().onAuthStateChanged(function(user)
{
if (user) {
// User is signed in
// ...
} else {
// User is signed out.
firebase.auth().signInAnonymously().catch(/*...*/);
}
// ...
});

Checking for signed in Google user with Google Sign-in

I'm working with the Google Sign-in library.
If I use Google's provided sign in button on my page, it quickly changes states to show that I am logged in before I've taken any action.
Is it possible to detect this signed in state without using Google's default button?
The main issue is that their button doesn't allow for checking for the hosted domain of the logged in account.
I was trying to use the GoogleAuth.currentUser.get() function to get the user, but as the documentation notes:
in a newly-initialized GoogleAuth instance, the current user has not been set. Use the currentUser.listen() method or the GoogleAuth.then() to get an initialized GoogleAuth instance.
Using GoogleAuth.then(onInit, onFailure) as mentioned above correctly retrieves the logged in state of the user.
/**
* The Sign-In client object.
*/
var auth2;
/**
* Initializes the Sign-In client.
*/
var initClient = function() {
gapi.load('auth2', function(){
/**
* Retrieve the singleton for the GoogleAuth library and set up the
* client.
*/
auth2 = gapi.auth2.init({
client_id: CLIENT_ID,
scope: 'profile'
});
// Called once auth2 has finished initializing
auth2.then(checkForLoggedInUser, onFailure);
});
};
function checkForLoggedInUser() {
var user = auth2.currentUser.get();
var profile = user.getBasicProfile();
console.log('Email: ' + profile.getEmail());
}
You can use the GoogleAuth.isSignedIn.get() method:
// 1. Make gapi.auth2 available (using gapi.load("auth2", ...))
// 2. Initialize the library (using gapi.init({ ... }))
const isSignedIn = gapi.auth2.getAuthInstance().isSignedIn.get();
isSignedIn is true if the user is signed to Google, otherwise false.

Categories