1

I have been using userCredential.additionalUserInfo!.isNewUser to check if the user is new but this method has a huge downside which i will explain. In my app, I want to check if the user is new then if yes I will direct him to profile info page otherwise, he will be directed to different page. with this method (isNewUser), the first time the user sign in, it will work fine but if the user sign in for the first time then for some reason he close the app or signout before submitting the profile page, the next time he sign in he will not be treated as new user and he will not be directed to the profile page.

I came up with a way that does work but it also has its downside.

  bool isExictedUser=false;


@override
  void initState(){
    super.initState();
    checkIfUserHasData();

  }

Future<void> checkIfUserHasData () async { // to check if the user has submitted a profile form before by checking if he has a name stored in the DB

    var data = await FirebaseFirestore.instance
        .collection('users')
        .doc(userID)
        .collection('personalInfo').doc(documentID)
        .get().then((value) {
         setState(() {
         name = value.get('name');

         });
    });
    if (name != null){
      setState((){
        isExictedUser = true;
      });
    }else {
      return;
    }
  }


 Widget build(BuildContext context) => isExictedUser
      ? const HomeScreen()
      :
     WillPopScope(
    onWillPop: _onBackPressed,
     child: Scaffold(

The problem with my method is that it takes few seconds to finish so even if the user is not new he will first be directed to the profile page for like 2 seconds until it confirm that he has a name stored.

Is there a way to optimize the (additionalUserInfo!.isNewUser) method or an alternative to keep showing the profile page until the user submit the form?

taha khamis
  • 401
  • 4
  • 22
  • Please check the stackoverflow url: https://stackoverflow.com/questions/51819652/check-if-user-is-new-using-firebase-authentication-in-flutter – Monali Ghotekar Jul 19 '22 at 12:25
  • @MonaliGhotekar I have mentioned in my question that I am using the "additionalUserInfo.isNewUser" method which is the method mentioned from the link you provided. However, I stated what was my problem with this method and why Its not sufficient enough for me. – taha khamis Jul 20 '22 at 01:01

4 Answers4

2

I usually keep a users' list in a Firebase database and manage users there.

Whenever a user authentication success, I input the same username into one of the databases (either Firestore or the Realtime Database) in firebase. Now this database can be used to check existing users.

Keep in mind that this part of the database should be open without any security rules so that it can be used before authentication.

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
Shanu
  • 311
  • 2
  • 16
  • Thanks for your response. unfortunately, this answer is not really helpful. please elaborate more on how can I make use of this to check if the user has signed in before and completed the profile or not – taha khamis Jul 18 '22 at 09:06
  • 1
    whenever a user authentication success I input the same username into one of the database(either firestore or realtime database) in firebase. Now this database can be user to check existing users. Keep in mind that this database should be open without any security rules so that it can be used before authentication. – Shanu Jul 18 '22 at 12:44
  • Thanks. I get you answer now. Its almost the same as what I am doing which I mentioned on my question. I am inputting the name and then using the name to check existing users but I was wondering if there is another way. Anyway, Thanks for the response, I appreciate your help – taha khamis Jul 19 '22 at 01:55
  • I believe that's an additional computation in terms of storage as well as processing when you have a large number of users. I posted an answer above. – Laxman Kumar Oct 24 '22 at 01:10
0

You can use FutureBuilder widget:

class MyFutureWidget extends StatelessWidget{

    @override
    Widget build(BuildContext context){
        return FutureBuilder<FirebaseUser>(
            future: FirebaseAuth.instance.currentUser(),
            builder: (BuildContext context, AsyncSnapshot<FirebaseUser> snapshot){
                       if (snapshot.hasData){
                           FirebaseUser user = snapshot.data; // this is your user instance
                           /// is because there is user already logged
                           return MainScreen();
                        }
                         /// other way there is no user logged.
                         return LoginScreen();
             }
          );
    }
}

For more information you can refer Documentation, stackoverflow thread, Firebase auth.

Monali Ghotekar
  • 359
  • 1
  • 7
  • Thanks for your response, but I dont think you understood the question clearly. Maybe you can read it again as I was not asking to check if the user is logged in or not. – taha khamis Jul 21 '22 at 05:28
0

One other way to check whether the user is a new user or not is to check inside AdditionalUserInfo. Field detail

Below is the code example of firebase phone authentication but the same can be replicated to other forms of authentication also.

 PhoneAuthCredential credential =
                        PhoneAuthProvider.credential(
                            verificationId: verificationId,
                            smsCode: smsCode);
                      
                        UserCredential userCred =
                        await auth.signInWithCredential(credential);
                        bool? isNewUser = userCred.additionalUserInfo?.isNewUser;
Laxman Kumar
  • 134
  • 6
0

I think you don't have any doubt about sign in with google, so I'm proceeding with only required code ->

if (signInAccountTask.isSuccessful) {
  try {
    val googleSignInAccount = signInAccountTask.getResult(ApiException::class.java)
    if (googleSignInAccount != null) {
      val authCredential: AuthCredential = GoogleAuthProvider.getCredential(
        googleSignInAccount.idToken, null
      )
      // Check credential
      firebaseAuth.signInWithCredential(authCredential)
        .addOnCompleteListener(this) { task ->

          if (task.isSuccessful) {
            // following statement will check user is signed in for the first time or not
            val newUserOrNot : Boolean = task.result.additionalUserInfo?.isNewUser
            // if newUserOrNot is true, then user is new 

            startActivity(Intent(this, ProfileActivity::class.java)
              .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK))
            finish()
            displayToast("Firebase authentication successful")
          } else {
            displayToast("Authentication Failed :" + (task.exception?.message))
          }
        }
    }
  } catch (e: ApiException) {
    e.printStackTrace()
  }
}

Hope this will help

Tyler2P
  • 2,324
  • 26
  • 22
  • 31