Not selecting an account in google account login in flutter bug on still entering the home page of the app

Viewed 68

So implementing this google account sign in feature for the app that I'm building and i encounter this bug on which if i dont select an account like click outside the pop up selection of google account or press the back button i can still enter the home page of the app, i dont know how to catch this error please help me, this is my code

 ElevatedButton.icon(
                                style: ElevatedButton.styleFrom(
                                  primary: Colors.white,
                                  onPrimary: Colors.black,
                                  minimumSize: const Size(double.infinity,50),
                                ),
                                icon: const FaIcon(FontAwesomeIcons.google, color: Colors.red,),
                                label: const Text("Login using Gmail"),
                                onPressed: () async{
                                  
                                  try {
                                    var result = await FirebaseServices().signInWithGoogle()..catchError((onError) => print(onError.toString()));

                                    if (result == null) return;
                                    
                                    Navigator.push(context, MaterialPageRoute(builder: (context)=> const HomePage()));
                                    
                                  // if (FirebaseServices().signInWithGoogle() == null) return;
                                  // Navigator.push(context,MaterialPageRoute(builder: (context)=> const HomePage()));
                                  
                                  }
                                  on FirebaseAuthException catch (e){
                                    print(e.message);
                                    throw e;
                                    }
                                },
                              ),

and here's my main.dart code

class _MyAppState extends State<MyApp> {

  late StreamSubscription<User?> user;
  @override
  void initState() {
    super.initState();
    user = FirebaseAuth.instance.authStateChanges().listen((user) {
      if (user == null) {

        print('User is currently signed out!');
      } else {
        print('User is signed in!');
      }
    });
  }

  @override
  void dispose() {
    user.cancel();
    super.dispose();
  }

  @override

  Widget build(BuildContext context) {
    return GetMaterialApp(
        initialRoute:
        // "/loginpage",

        FirebaseAuth.instance.currentUser == null ? LoginPage.id : HomePage.id,
        routes: {
          // "/homepage": (context)=> const HomePage(),
          // "/loginPage" : (context)=> const LoginPage(),
          
          LoginPage.id: (context) =>const LoginPage(),
          HomePage.id: (context) => const HomePage(),
          
        },
        home: const LoginPage(),
      );
    
  }

  
}

and here's my google service code

class FirebaseServices{
  final _auth = FirebaseAuth.instance;
  final _googleSignIn = GoogleSignIn();
  final _formkey = GlobalKey<FormState>();

var context;

  signInWithGoogle() async{
    //if(_formkey.currentState!.validate()){
      try{
      final GoogleSignInAccount? googleSignInAccount =
          await _googleSignIn.signIn().catchError((onError)=>print(onError));
          //plugin
          if (googleSignInAccount == null) return null;
          // ignore: unused_local_variable
          final GoogleSignInAuthentication googleSignInAuthentication = await googleSignInAccount.authentication;
          //end plugin
      if (googleSignInAccount!=null){
        final GoogleSignInAuthentication googleSignInAuthentication =
            await googleSignInAccount.authentication;
        final AuthCredential authCredential = GoogleAuthProvider.credential(
          accessToken: googleSignInAuthentication.accessToken,
            idToken: googleSignInAuthentication.idToken);
        await _auth.signInWithCredential(authCredential)
            .then((value) => {
          postDetailsToFirestore(),
        }
        ).catchError((e)
        {
          Fluttertoast.showToast(msg: e!.message);
        });
       
      }
    }on FirebaseAuthException catch (e){
      print(e.message);
      throw e;
    //}

    }
    
    
  }

  signOut() async{
    await _auth.signOut();
    await _googleSignIn.signOut();
  }
  postDetailsToFirestore() async{

    //calling firestore,calling user model, sending values

    FirebaseFirestore firebaseFirestore = FirebaseFirestore.instance;
    User? user = _auth.currentUser;

    UserModel userModel = UserModel();

    //writing values
    userModel.email = user!.email;
    userModel.uid = user.uid;
    userModel.fullname = user.displayName;
    userModel.profileimage=user.photoURL;


    await firebaseFirestore
        .collection("Users")
        .doc(user.uid)
        .set(userModel.toMap());

    
  }
} 

here's a video about the bug enter image description here here's the newest bug

enter image description here

2 Answers

When you are first calling the FirebaseServices.signInWithGoogle().catchError(); You are awaiting an error result. I would suggest you that you call it in this way:

try {
    // Here, we use the .. (cascade) operator, which will give us the
    // reference to the correct future that signInWithGoogle() returns.
    var result = await FirebaseServices().signInWithGoogle()..catchError((onError) => print(onError.toString()));

    // If we didn't sign in, then do not proceed to the home screen
    if (result == null) return;

    // We push a replacement route so that when the user 
    // consecutively presses the back button, he doesn't reach the
    // login screen before exiting the app.
    Navigator.pushReplacement(context, MaterialPageRoute(builder: (context)=> const HomePage()));
} on FirebaseAuthException catch(e) {
    print(e.message);
    // Do not throw an exception in your production app. It will make the app crash. Instead, 
    // display it to the user with a Dialog.
    throw e;
}

If my answer was helpful, please mark my answer as Correct. Thank you!

Also, I recommend you to follow @Saichi Okuma's answer, as that is the correct approach to signing-in the user in a production app.

Related