Is firebase checking for user first time - firebase

On initial load, firebase tells me, if user is logged in by firing event like this:
firebase.auth().onAuthStateChanged(func...)
I want to check, if firebase is still checking it. Like show spinner when page loads, wait for firebase to check user and then show app or login/register form, considering user found or not.
Now I just have to show page, then init firebase, and later, if firebase founds user, redirect to app.

Swift 4
Method 1
Check if the automatic creation time of the user is equal to the last sign in time (Which will be the first sign in time if it is indeed their first sign in)
//Current user metadata reference
let newUserRref = Auth.auth().currentUser?.metadata
/*Check if the automatic creation time of the user is equal to the last
sign in time (Which will be the first sign in time if it is indeed
their first sign in)*/
if newUserRref?.creationDate?.timeIntervalSince1970 == newUserRref?.lastSignInDate?.timeIntervalSince1970{
//user is new user
print("Hello new user")
}
else{
//user is returning user
print("Welcome back!")
}
Method 2
ALTERNATIVELY, you can set a global var in App Delegate. Most apps I've worked on use automatic Firebase login if the user already exists; meaning that it will not update the lastSignInDate value and thus still show the user as a new user.
So start by creating a variable in AppDelegate above the class like so:
var newUser = false
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate{
Then whenever you call your function to create a new Firebase user, set newUser to true:
newUser = true
Lastly, make an if statement that filters which user your main controller is receiving:
Override func viewDidLoad() {
super.viewDidLoad()
if newUser == true{
print("welcome new user")
showOnboarding()
}
else{
print("Welcome back!")
}
}
Now anytime an existing user logs in, the variable will remain false

The listener passed to onAuthStateChanged will be called with an argument that is either null or the User instance.
So it's safe to assume that Firebase is checking the authentication status between your calling of initializeApp and the listener for onAuthStateChanged being called. Display the spinner when you call initializeApp and hide it when the listener is called.

You can use the FIRAuthDataResult object returned in the successful sign-in to determine whether the user is new from the additionalUserInfo property:
Auth.auth().signIn(with: credential) { (authResult, error) in
if let error = error {
print(error.localizedDescription)
return
}
// User is signed in
// ...
//Check if new user
if let isNewUser: Bool = authResult?.additionalUserInfo?.isNewUser {
if isNewUser {
print("new user")
}
}
}

Related

Cannot get the currentUser's displayName with FirebaseAuth

I have made a sign-in page, and a sign-up page with Firebase Authentication in Flutter and Dart.
After the sign up, I'm trying to retrieve the current user's displayName, however, when I try retrieving it, I seem to get not the current one, but the one that I signed up with before this one.
However, when I for example hot-restart the app, I get the current user's details just fine.
I try to retrieve the current user's displayName property with this code:
static String? getUsername() {
return FirebaseAuth.instance.currentUser?.displayName!;
}
The way I call this, is I initialize a variable to store the username which I get from the method, on a different dart file, different from the signUp page I got. I also call this method in the initState() method.
This is how I sign-up the user and set the displayName:
static void signUpUser(String username, String emailAddress, String password) async {
try {
final credential =
await FirebaseAuth.instance.createUserWithEmailAndPassword(
email: emailAddress,
password: password,
);
// Here I set the displayName property
await credential.user!.updateDisplayName(username);
} on FirebaseAuthException catch (e) {
if (e.code == 'weak-password') {}
else if (e.code == 'email-already-in-use') {}
} catch (e) {}
}
I tried to use the user.reload(), and FirebaseAuth.userChanges() functions, but these did not seem to fix my problem.
Maybe I'm trying to retrieve the displayName property wrong, what am I missing? I'm quite new to developing my own apps and working with Firebase.
The Future that updateDisplayName returns completes when the call has been made to the underlying Firebase SDK. It does not automatically update the user profile in your application at that point though. That will only happen automatically once every hour (when the SDK refreshes the ID token on which that profile is based), or when the user signs out and in again.
To force a refresh of the profile from your application code outside of those automatic conditions, you can call reload() on the user object.

Persisting user login credentials

I am using Firebase email and password authentication in my Angular 6 project, and want to persist the user login credentials for a browser session.
Once a user is logged in and I press F5 the user appears to no longer be logged in.
looking at the firebase documentation (https://firebase.google.com/docs/auth/web/auth-state-persistence#supported_types_of_auth_state_persistence), I should be able to set the persistence for the session by calling the method -
firebase.auth().setPersistence(firebase.auth.Auth.Persistence.SESSION))
any idea where this code should go to properly implement this please?
_loggedIn = new BehaviorSubject<boolean>(false);
constructor(
public _fireAuth: AngularFireAuth) {
_fireAuth.auth.onAuthStateChanged(function (user) {
if (user) {
this._loggedIn = true;
console.log("onAuthStateChanged = true ");
} else {
console.log("onAuthStateChanged false ");
this._loggedIn = false;
}
});
}

Firebase how to get user details?

I am using Firebase authentication in my app and signing up a user with email and password. I want to get other users details (separate from the logged-in user) as well while a user is signed in with their own account. How can I get that information?
Values like email, display name and id (specific to authentication system) are available off of the Firebase User object. You can get a reference to the current logged in user off of the FIRAuth class. I provided links and class names for iOS, but other platforms are similarly structured.
If you want to store additional data for users, I would recommend including a users root node, using the uid off of the Firebase User object as the key for users child nodes.
//create user
auth.createUserWithEmailAndPassword(email, password)
.addOnCompleteListener(SignupActivity.this, new OnCompleteListener < AuthResult > () {
#Override
public void onComplete(#NonNull Task < AuthResult > task) {
Toast.makeText(SignupActivity.this, "createUserWithEmail:onComplete:" + task.isSuccessful(), Toast.LENGTH_SHORT).show();
progressBar.setVisibility(View.GONE);
// If sign in fails, display a message to the user. If sign in succeeds
// the auth state listener will be notified and logic to handle the
// signed in user can be handled in the listener.
if (!task.isSuccessful()) {
Toast.makeText(SignupActivity.this, "Authentication failed." + task.getException(),
Toast.LENGTH_SHORT).show();
} else {
String user_id = auth.getCurrentUser().getUid();
DatabaseReference current_user_db = _Database.child(user_id);
current_user_db.child("name").setValue(name);
current_user_db.child("image").setValue("default");
startActivity(new Intent(SignupActivity.this, ProfileActivity.class));
finish();
}
}
});
}
});
It's not a security issue, but just a mean of how you treat personal information. You can store what you want in firebase so you can easily store when the user login his/her avatar url (aka facebook url) or just id or any other infos anyway, then retrieve it.
If you need to retrieve infos of users which are not using your apps beside, thden you can also easily via the facebook sdk with user permission of course. take care–

Meteor-Useraccounts and Accounts.onCreateUser

Am using meteor-useraccounts and alanning:roles in my Meteor webapp. The idea is that a user can register and automatically gets assigned a role. So I was thinking of using the Accounts.onCreateUser hook, however can't get that to work.
Accounts.onCreateUser(function(options, user) {
var user = user.user;
var defaultRole = ['admin'];
if (!user.roles){
Roles.addUsersToRoles(user, defaultRole);
}
});
I'm getting the following error message:
Exception while invoking method 'ATCreateUserServer' TypeError: Cannot read property 'roles' of undefined
Seems that the user is not known, hence undefined. Can you user Meteor-useraccounts and assign a role upon user creation.
NEW EDIT: tried a bit further and the below code is working but I'm not really in favor of using this as it is strange to add the role each time upon login of the user:
Accounts.onLogin(function(user) {
check(user, Object);
var user = user.user;
var defaultRole = ['admin'];
if (!user.roles){
Roles.addUsersToRoles(user, defaultRole);
}
return user;
});
There are always many ways to do that. On of which is to add the roles after the user is created and officially obtained a userId, like so:
var id = Accounts.createUser(
createOptions
);
Roles.addUsersToRoles(id, ["user","guest"]);
If you want to add roles using the hook onCreateUser you could extend the user object, like so:
Accounts.onCreateUser(function(options, user)
{
if(!options || !user) {
throw new Meteor.Error('Problem to create new user');
return;
}
var user_extend =
{
username: options.username,
email: options.email,
profile: options.profile,
roles: ["user","guest"]
};
_.extend(user,user_extend);
return user
}
I prefer method number one because you can decide when and where you want to at the roles to that user because you will set those roles to every user that registers on your site. I hope it helps.

Log a user in using a generated Anonymous Login ID

I am writing an Android application and I am trying to log users in anonymously so they don't have to go through any sort of registration process. I am storing their anonymous user ID in shared preferences, and when the application opens, I am trying to log them in based on that user ID. I am trying to figure out the correct way to do this, as there doesn't seem to be an auth function that just takes in a UID. Currently I have it using auth(), but I don't feel like that is correct.
Here is some sample code:
String userID = getUserID();
if(userID.equals("NOT_FOUND")) {
ref.authAnonymously(new Firebase.AuthResultHandler() {
#Override
public void onAuthenticated(AuthData authData) {
//successful authentication
//save auth data
SharedPreferences prefs = getSharedPreferences(
"USER_ID", Context.MODE_PRIVATE);
String id = authData.getUid();
prefs.edit().putString("USER_ID", id).commit();
}
#Override
public void onAuthenticationError(FirebaseError firebaseError) {
//unsuccessful authentication
}
});
} else {
ref.auth(userID, new Firebase.AuthListener() {
...
You're creating a new authentication session each and every time you invoke FirebaseRef.authAnonymously(...). This method only needs to be invoked once, after which the user will authenticated upon page refreshes. Also note that you do not need to call FirebaseRef.auth() again once restarting the application, as that piece is automatically handled for you.
If you'd like to check for the current authentication state of the user, and only then create a new authentication session if the user is not currently authenticated, use the synchronous accessor for authentication state FirebaseRef.getAuth().
Lastly, once you create an anonymous authentication session, no new sessions may ever be created with the same uid. That session will live until your predefined session expiration time (configured in your account dashboard) or until your user logs out, after which that uid is permanently retired.

Resources