Firebase/auth currently in version 9 stores by default the session locally inside indexedDB. But I can't find a method within firebase to retrieve the local session when loading the application.
onAuthStateChanged takes time to get the auth ready when it should be possible to retrieve the "saved current user session".
auth.onAuthStateChanged(function (userData) {
if (userData) {
// User is signed in.
} else {
// No user is signed in.
}
});
Is there a method to access the local current user directly without accessing manually to the indexedDB? rather than dumpling the indexedDB like in this gist, or sending the user to localStorage myself?
You are probably looking for this:
import { getAuth } from "firebase/auth";
const auth = getAuth();
const user = auth.currentUser; // null if no user
You can find more information in the documentation
Related
I see how execute a Cloud Function on user account creation:
exports.myFunction = functions.auth.user().onCreate(event => {
But I need my function to execute when the user logs in. Is there a onLogin trigger?
And can someone with 1500 points create a tag for firebase-cloud-functions?
There's no event for login, because only the client side can define exactly when a login happens. Different clients may define this in different ways. If you need to trigger something on login, figure out when that point is in your app, then trigger it from the client via a database or HTTP function.
This worked in the controller:
firebase.auth().onAuthStateChanged(function(user) { // this runs on login
if (user) { // user is signed in
console.log("User signed in!");
$scope.authData = user;
firebase.database().ref('userLoginEvent').update({'user': user.uid}); // update Firebase database to trigger Cloud Function
} // end if user is signed in
else { // User is signed out
console.log("User signed out.");
}
}); // end onAuthStateChanged
And this is the trigger in the Cloud Function:
exports.getWatsonToken = functions.database.ref('userLoginEvent').onUpdate(event => { // authentication trigger when user logs in
I made a location in Firebase Database called userLoginEvent.
One confusing bit is that in the functions console it's /userLoginEvent but in your code you must leave out the slash.
You can create your own analytics event, like login and used it as the trigger for your cloud function.
Then in your app, when the user successfully authenticate you use firebase analytics to send an event with the name you defined, like login
exports.sendCouponOnPurchase = functions.analytics.event('login').onLog((event) => {
const user = event.user;
const uid = user.userId; // The user ID set via the setUserId API.
});
You can trigger an https onCall firebase cloud function on login
ex: This is your login button trigger function which calls an https onCall function after authenticating the user.
_login() {
firebase
.auth()
.signInWithEmailAndPassword(this.state.email, this.state.password)
.then(function (user) {
var addMessage = firebase.functions().httpsCallable('myCloudFunctionName');
addMessage("whatever variable I want to pass")
.catch(error => {
console.log("I triggered because of an error in addMessage firebase function " + error)
)}
}).catch(error => {
console.log(error);
});
}
There is also another way you can do this inside Google Cloud if you enable Identity Platform for a project. Then you can follow this guide:
https://cloud.google.com/functions/docs/calling/logging
And trigger cloud functions for any of these Firebase Authentication events:
https://cloud.google.com/identity-platform/docs/activity-logging?authuser=1&_ga=2.226566175.-360767162.1535709791#logged_operations
The only problem I've just noticed is that the logs generated for Sign In event do not include the firebase app id or anything to determine which client the user logged in on which is really annoying as this was the main reason we needed to do this!
I couldn't find a similar question so I will ask here:
I'm using the Realm library and the react-native SDK to build an app.
I started by running the example app https://github.com/mongodb-university/realm-tutorial-react-native
I can start the app in xcode, login, and register, and even add a task, but every time I try to get the current user that is signed to the app it gives me an empty object.
For example I have tried to log the user (code is taken from the repo mentioned above - Auth Provider):
const signIn = async (email, password) => {
const creds = Realm.Credentials.emailPassword(email, password);
const newUser = await app.logIn(creds);
console.log('====', { newUser, creds, app: app.currentUser });
setUser(newUser);
};
The log I get is: LOG ==== {"app": {}, "creds": {}, "newUser": {}}
As I mentioned the app is WORKING and I can see the users and tasks added OK on the Realm UI app. What am I missing? How can I get the user?
(I would like to save it in a secured storage and in the app state to change the screens depending on the auth state of the user)
in a VueJS / QuasarJS application Im using firebase-js-sdk [1] together with firebaseui-web [2] to handle authentication.
After successful auth with any of the configured providers (e.g. password, google, apple, etc) I want to check which provider the user used. But immediately after successful authentication the user.providerData[] array that should contain the information is empty.
BUT if I reload my app the user.providerData[] array is suddenly populated correctly.
Iยดm checking for user data with something like this
import { getAuth } from "firebase/auth";
const auth = getAuth();
const user = auth.currentUser;
if (user) {
console.log(user.providerData)
}
After that the user object is fully populated (incl auth tokens, etc) but the user.providerData[] array is empty. Only after a page reload (CTRL-R) does the array get populated.
I searched both projects issues pages and documentation and didnt find anything that could explain this.
Im thankful for ANY idea where to look next!
EDIT
As suggested by #aside Im using onAuthStateChanged to check for updates of the user state.
onAuthStateChanged(
fbAuth,
(user) => {
if (user) {
console.log("onAuthStateChanged: user found");
console.log("onAuthStateChanged: user.providerData", user.providerData);
console.log("onAuthStateChanged: user", user);
} else {
console.log("onAuthStateChanged: no user found");
}
},
function (error) {
console.log("onAuthStateChanged:", error);
}
);
But even if I wait minutes after authentication is completed, still the user.providerData array is only populated after a page reload.
Here is a full demo: https://codesandbox.io/s/github/perelin/firebase-auth-providerdata-test
Thanks in advance :)
Im using
"firebase": "9.6.1",
"firebaseui": "6.0.0",
[1] https://github.com/firebase/firebase-js-sdk
[2] https://github.com/firebase/firebaseui-web
Your app should call getAuth().currentUser.reload() to refresh the local user data after login.
This could be done either in beforeRouteEnter() nav guard of the LoggedIn view:
// LoggedIn.vue
import { getAuth, signOut } from "firebase/auth";
export default {
async beforeRouteEnter(to, from, next) {
await getAuth().currentUser?.reload() ๐
next()
},
}
demo 1
Or in the onAuthStateChanged callback:
// main.js
onAuthStateChanged(
fbAuth,
async (user) => {
await user?.reload() ๐
},
)
demo 2
Your code is only running once instead of running every time the auth state is updated.
If you want to listen to any changes to the auth state, use a callback along with onAuthStateChanged as described here.
https://firebase.google.com/docs/auth/web/manage-users#get_the_currently_signed-in_user
import { getAuth, onAuthStateChanged } from "firebase/auth";
const auth = getAuth();
onAuthStateChanged(auth, (user) => {
if (user) {
// Check used provider here
const providerData = user.providerData;
// ...
} else {
// User is signed out
// ...
}
});
The reason checking/requesting the user object right after authentication does not work is that it might take firebase a second to update the providerData array. signInWithX might therefore return before the property is updated.
Hi every one I want to set Auth state persistence on firebase to local i'm working on flutter and I don't know how to do that
I found this on firebase web site
import { getAuth, setPersistence, signInWithEmailAndPassword, browserSessionPersistence } from "firebase/auth";
const auth = getAuth();
setPersistence(auth, browserSessionPersistence)
.then(() => {
// Existing and future Auth states are now persisted in the current
// session only. Closing the window would clear any existing state even
// if a user forgets to sign out.
// ...
// New sign-in will be persisted with session persistence.
return signInWithEmailAndPassword(auth, email, password);
})
.catch((error) => {
// Handle Errors here.
const errorCode = error.code;
const errorMessage = error.message;
});
but not sure how I do that on flutter if any one can help with that
As per the FlutterFire documentation
On native platforms such as Android & iOS, this behavior is not configurable and the user's authentication state will be persisted on-device between app restarts. The user can clear the apps cached data via the device settings which will wipe any existing state being stored.
If you're using Flutter for a web app, by default the auth state is stored in local storage. If you want to change this to session based or no persistence you would set that like this:
// Disable persistence on web platforms
await FirebaseAuth.instance.setPersistence(Persistence.NONE);
in web i have firebase project with two database instances in the same project / app
after successful login with firebase auth;
the second database reference seems to be non authenticated and thus the database access fail; with auth != null in rules.
if i replace the second database url in config object and put default database url in config2 the second database than starts to work fine authenticated but old database fails with database access rule auth != null
How can i use both database in web javascript code without anyone having the above issue ?
Is the initialisation done correctly ?
Thanks in Advance
Should be documented properly in firebase documentation for Auth in web
but unfortunately its not for this question.
So the firebase auth instances are maintained separately including the auth callback
So i had to do like bellow
await firebase.auth().signInWithEmailAndPassword(_ths.form.email, _ths.form.password);
await firebase.app('app2').auth().signInWithEmailAndPassword(_ths.form.email, _ths.form.password);
let authPromises = [];
authPromises.push(new Promise((resolve,reject)=>{
firebase.auth().onAuthStateChanged(function (user) {
if (user) resolve(user);
});
}));
authPromises.push(new Promise((resolve,reject)=>{
firebase.app('app2').auth().onAuthStateChanged(function (user) {
if (user) resolve(user);
});
}));
Promise.all(authPromises).then(async(users)=>{
// ....
let oldDbInstance = firebase.database();
let newDbInstance = firebase.database(app2);
});
Phew!!!