69

I am using Firebase Authentication in an Android application, and I am using Google account authentication as an option to sign in to the application.

How can I know if the user is signed in to the application for the first time or not?

4
  • So you want to use retrieve a list of all user using Firebase Auth? Sep 17, 2016 at 23:46
  • yes it is exactly what I am looking for
    – rainman
    Sep 17, 2016 at 23:48
  • Unfortunately you can't use Firebase Auth in that manner. You would have to follow what @NarenderReddy says - each time a user logs in for the first time you'll need to store some kind of entry using the Firebase Database (or your preferred storage method) along with the info you want to track. Then you can use that database location to get a list of all users. Sep 17, 2016 at 23:53
  • OK, as you know everytime a user is registred in my app I store an ID for him, but the problem is that i am not able to make a query on the database, when the user is signing in, i only found examples with the dataSnapshot childEventListener, this is why I asked an other question here: stackoverflow.com/questions/39552168/…
    – rainman
    Sep 18, 2016 at 0:01

12 Answers 12

62

To check if it's the first time user logs in, simply call the AdditionalUserInfo.isNewUser() method in the OnCompleteListener.onComplete callback.

Example code below, be sure to check for null.

OnCompleteListener<AuthResult> completeListener = new OnCompleteListener<AuthResult>() {
        @Override
        public void onComplete(@NonNull Task<AuthResult> task) {
            if (task.isSuccessful()) {
                boolean isNew = task.getResult().getAdditionalUserInfo().isNewUser();
                Log.d("MyTAG", "onComplete: " + (isNew ? "new user" : "old user"));
            }
        }
    };

Check the docs for more reference AdditionalUserInfo

4
  • It's not working, I declared it under onCreate() but it's never ran
    – Sandeep
    Nov 20, 2018 at 17:00
  • @Sandeep can you be more specific of what's not working. Some code snippets would also be very helpful Nov 24, 2018 at 16:03
  • @erict how to do it in flutter ?
    – user12021836
    Dec 29, 2019 at 21:02
  • @puzzled In Flutter, you can grab result.additionalUserInfo.isNewUser property from AuthResult. Jan 5, 2020 at 20:53
18

From the Firebase-ui docs, you can check the last sign-in timestamp against the created-at timestamp like this:

FirebaseUserMetadata metadata = auth.getCurrentUser().getMetadata();
if (metadata.getCreationTimestamp() == metadata.getLastSignInTimestamp()) {
    // The user is new, show them a fancy intro screen!
} else {
    // This is an existing user, show them a welcome back screen.
}
5
  • It's possibly a Firebase bug - check a related post here: stackoverflow.com/q/48079683/1145905
    – kip2
    Nov 20, 2018 at 17:34
  • but it show the fancy intro screen after refresh the page too. i don't want to show the fancy intro screen after refresh.
    – Dharan
    Apr 30, 2019 at 9:54
  • 5
    These were returning 2 milliseconds apart for me for Google sign-in, it's not reliable. It was only working as intended for email authentication. Jun 5, 2019 at 5:51
  • Agreeing with @Anthony. This does not work with google sign in.
    – Steve
    Mar 24, 2020 at 22:19
  • I've tried it with Flutter phone auth, there is difference between the timestamps for the user just created.
    – shuster
    Feb 10, 2023 at 10:39
8

According to the new version of Firebase auth (16.0.1) The AuthResult class has a member function which results true or false (is the user is new). Assuming "credential" is defined in the scope(it is the google credential ). An example is shown below: `

private FirebaseAuth mAuth;

GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestIdToken(getString(R.string.default_web_client_id))
            .requestEmail()
            .build();

mAuth = FirebaseAuth.getInstance();
Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data);
GoogleSignInAccount acct = task.getResult(ApiException.class);
AuthCredential credential = GoogleAuthProvider.getCredential(acct.getIdToken(), null);

mAuth.signInWithCredential(credential)
            .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
                @Override
                public void onComplete(@NonNull Task<AuthResult> task) {
                    if (task.isSuccessful()) {
                        Log.d(TAG, "linkWithCredential:success");


                        boolean newuser = task.getResult().getAdditionalUserInfo().isNewUser();



                        if(newuser){

                             //Do Stuffs for new user

                         }else{

                            //Continue with Sign up 
                        }

                    } else {

                        Toast.makeText(MyClass.this, "Authentication failed.",
                                Toast.LENGTH_SHORT).show();

                    }


            });

Thanks to firebase:)

1
  • 1
    not working it's always going to the 'Sign up' condition
    – Sandeep
    Nov 20, 2018 at 18:19
6

For Web, version 9.0 (modular):

You will need to import "getAdditionalUserInfo" and call it as such:

signInWithPopup(firebaseAuth, provider)
  .then((result) => {
    const details = getAdditionalUserInfo(result)
    console.log(details.isNewUser);
  })
  .catch((error) => {
    console.log(error);
  });

The details returned includes an "isNewUser" boolean property.

Details on GitHub from August 2021

4

From version 11.6.0 we can use AdditionalUserInfo.isNewUser()

https://firebase.google.com/docs/reference/android/com/google/firebase/auth/AdditionalUserInfo

2

Workaround I used-

  1. Created a collection in Firestore named 'Users'.
  2. Whenever someone signs in, get its uid
  3. Search for that uid in the 'Users'. Make sure to name 'Users' documents = user's UID.
  4. If the document exists, then its the new user, if it doesn't
  5. then add that particular user's doc in that collection 'Users'.

Trick Used - Use UID to solve this problem. Thanks, upvote if helpful

1

A solution when you use Firebase Auth together with Firestore

The root architecture of the Firestore Database would look like this enter image description here

Use the Firebase Auth currentUser.uid to create a root document for each user. Start by adding a field called registered_at to the root document as soon as the user is created the first time and then add your specific collections to your root document depending on your use case.

When logging in or signing in you can then check if the document with the registered_at field already exists. If it doesn't exist yet, then you can treat the user as a new user (assuming the user can not delete or alter the registered_at field later)

import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.firestore.DocumentReference
import com.google.firebase.firestore.FirebaseFirestore

fun rootDocument(): DocumentReference? = rootPath()?.let {
    return fireStore().document(it)
}

fun rootPath(): String? {
    val loggedInUser = loggedInUser()
    if (loggedInUser != null) {
        return "users/${loggedInUser.uid}"
    }
    return null
}

fun fireStore() = FirebaseFirestore.getInstance()

fun createWriteBatch() = fireStore().batch()

fun loggedInUser() = fireAuth().currentUser

fun fireAuth(): FirebaseAuth = FirebaseAuth.getInstance()

fun afterSignIn() {

    val rootDocument = rootDocument()
            ?: throw IllegalStateException("root document not found")

    rootDocument.get().addOnCompleteListener {
        val isNewUser = it.result.exists().not()

        if (isNewUser) {
            val batch = createWriteBatch()

            batch.set(rootDocument, HashMap<Any, Any>().apply {
                put("registered_at", System.currentTimeMillis())
            })

            batch.commit().addOnCompleteListener {
                println("this is a new user")
            }

        } else {
            println("this is not a new user")
        }
    }
}
1

While I fully agree that the most correct way (given the inability to add new fields to the auth user table) is to create a new path for users and store info there, I didn't want to make an additional request after logging in to do this check (I'm using Firestore and requests = money).

I needed to do this first login check to prompt for a userName (as display name is pulled from Facebook/Google and I wanted to give the option of overriding if it's their first login). What I ended up doing was using the photoURL property as a flag to determine if it was their first time or not. It's not ideal but maybe someone that wants to save on requests can use this as a workaround. It's not as big a deal for Firebase but for Firestore it's more costly for your plan

1

In Firebase UI, JAVA:

 @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        Intent i;


        if (requestCode == RC_SIGN_IN) {
            IdpResponse response = IdpResponse.fromResultIntent(data);

            if (resultCode == RESULT_OK) {


                if(response.isNewUser()){
                Log.d(TAG, "onActivityResult: isNewUser "+response.isNewUser());
} else {

                // Successfully signed in
                }

                // ...
            } else {



//               handle error
            }
        }
    }

1

Firebase V9 (modular)

Here is a function that worked for me

function isNewUser(auth) {
    let newUser;
    const metadata = auth.currentUser.metadata;
    if (metadata.creationTime == metadata.lastSignInTime) {
      newUser = true;
    } else {
      newUser = false;
    }
    return newUser;
  }

You could use a shorter way:

  function isNewUser(auth) {
    const metadata = auth.currentUser.metadata;
    return metadata.creationTime == metadata.lastSignInTime ? true : false;
  }

I have seen something similar that uses functions on the metadata like metadata.getCreationTimeStamp() but that did not work for me.

Hope that helps!

0

This may help you and try it:

Correct code location to check Firebase if a user has been created already?

1
  • 1
    @adityashrivastava Your SO question refers to the Firebase database (Realtime Database) the user has set. wants to be able to solve it only with Firebase (Authentication)
    – Rafael
    May 7, 2017 at 16:28
0

First of all Check - if current user uid match with your documents id then it's old user otherwise it's new user

Example

private boolean isUserMatch(String currentUserId) {
    firestore.collection(COLLECTION_USER).get().addOnCompleteListener(new OnCompleteListener< QuerySnapshot >() {
        @Override
        public void onComplete(@NonNull @NotNull Task< QuerySnapshot > task) {
            if (task.isSuccessful()) {
                for (QueryDocumentSnapshot documentSnapshot : task.getResult()) {
                    if (currentUserId.equals(documentSnapshot.getId())) {
                        return;
                    }
                }
            }
        }
    }).addOnFailureListener(new OnFailureListener() {
        @Override
        public void onFailure(@NonNull @NotNull Exception e) {
            Log.e(TAG, "onFailure: ", e.getCause());
        }
    });
    return false;
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.