I'm attempting to implement a "Keep me signed-in" check box when the user signs-in. If the checkbox is checked then the user should remain signed-in until they explicitly sign-out. If not checked, the user should only remain signed-in until they close the app.
The Flutter Firebase Authentication package doesn't have a method for configuring the authentication duration, or at least I've not found a method.
I've tried to listen for when the app is shutting down using the WidgetsBindingObserver's didChangeAppLifecycleState(..) method's AppLifecycleState.detached state. I can see the signOut() method called, but despite this the user remains signed-in the next time they launch the app. I'm not surprised given that the app is in the middle of exiting.
#override
void didChangeAppLifecycleState(AppLifecycleState state) {
if( state == AppLifecycleState.detached ){
FirebaseAuth.instance.signOut();
}
}
Am I missing any good options?
By default the Firebase Authentication SDKs persist the authentication state to local storage, and then restore it from there when the app restarts.
If you want the state to not be persisted, you can configure that when the app starts by calling:
await FirebaseAuth.instance.setPersistence(Persistence.NONE);
Also see the FlutterFire documentation on persisting authentication state.
That's because signOut() returns a Future. So you'll have to await it. So, suppose you have a function userSignOut.
Future<void> userSignOut() => FirebaseAuth.instance.signOut();
And you use it on a button...
IconButton(
icon: const Icon(Icons.exit_to_app),
onPressed: () async {
await userSignOut();
},
)
This should solve your issue. If it still doesn't work, provide more relevant code.
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)
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);
I'm working on a flutter app with firebase as a backend and an authentication, now I want the app to have a trial version where the user can signInWithGoogle and use the app with full features ( for like one hour ), and then signs out automatically after that one hour ends.
SO FAR, I accomplished the following:1- signIn with google account.
2- add signed in user to _trial collection with timeStamp.
Future enterTrial() async {
final UserCredential user = await Auth.instance.googleSignInMethod();
final User actualUser = user.user;
try {
//_trial is a collection for users in Trial Period
await _trial.doc(actualUser.email).set({.
"name": actualUser.displayName,
"email": actualUser.email,
"creationDate": FieldValue.serverTimestamp(),
});
} catch (e) {
print(e);
}
}
WHAT's LEFT:
after one hour from signIn, signOut and move user from _trial collection to _expired collection.
so that I could check if the user is expired or not.
is there a way to automatically signOut after sometime? or to - periodically - compare creationTime with currentTime and accordingly signOut?
Thanks In Advance.
Yes You can achive this by using background_fetch package this provide you a callback function in that function you can call your logout method.
I used firebase_auth package to work with flutter. And I used phone authentication to sign in. Everything is working well. But when signout user is not deleted on firebase.
Is it possible to delete firebase user?
RaisedButton(
onPressed: () async {
await FirebaseAuth.instance.signOut();
}
)
I tried this way,
but error is coming..
delete called null
_auth.onAuthStateChanged.listen((currentUser)=>{
currentUser.delete()
}).onError((e)=>print("Error is $e"));
Yes. You must use FirebaseAuth.instance.currentUser.delete() method before (on) signOut() method.
RaisedButton(
onPressed: () async {
FirebaseAuth.instance.currentUser.delete();
await FirebaseAuth.instance.signOut();
}
)
You can't delete the current user after they've signed out, because at that point there is no current user anymore.
But you can prevent this whole chicken-and-egg problem by simply deleting the user without signing out. This should be all that is needed for that:
currentUser.delete()
You can call this operation "logging out" for your users of course, but in code you're simply deleting their account.