56

I have a problem signing out the current user from my app

the method I am using is as follows:

....
onPressed:_signOut
//jump to function


  void _signOut() {
  FirebaseAuth.instance.signOut();
  FirebaseUser user = FirebaseAuth.instance.currentUser;
  //print('$user');
  runApp(
      new MaterialApp(
        home: new LoginPage(),
      )

  );
}

So now when I press the button it should sign the user out and redirect them to the home page which they will have to login again, however, the redirecting happens but the user data would still be saved so when I press the button again it automatically sign in again with the last account. How can I remove user data so the app asks about their credentials each time they try to login after a logout ?

I feel I am missing something in the linkage between pages and how their behavior change accordingly, but what is it ?

Update: I use google sign in function with firebase authentication

   Future<String> _testSignInWithGoogle() async {
  final GoogleSignInAccount googleUser = await _googleSignIn.signIn();
  final GoogleSignInAuthentication googleAuth =
  await googleUser.authentication;
  final FirebaseUser user = await _auth.signInWithGoogle(
    accessToken: googleAuth.accessToken,
    idToken: googleAuth.idToken,
  );
  assert(user.email != null);
  assert(user.displayName != null);
  assert(!user.isAnonymous);
  assert(await user.getToken() != null);
return 'signInWithGoogle succeeded: $user';
}

My login page looks like this:

    class LoginPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {

    return new Scaffold(
        appBar: new AppBar(
          title: new Text("Login"), backgroundColor: Colors.blue,),
        body: new Container(
            child: new Center(
                child: new Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: <Widget>[
                    new IconButton(
                      icon: new Icon(Icons.account_box, color: Colors.red),
                      onPressed:  _signIn,
                      iconSize: 80.0,),
                    new Text("Google Signin")
                  ],
                )
            )
        )
    );
  }
}

Update: Changed _signOut() method to be async as follows:

    Future <LoginPage> _signOut()  async{
    await FirebaseAuth.instance.signOut();

    return new LoginPage();
}

Now when I press on signout, it does not redirect me to the LoginPagae nor does it sign the user out.

7
  • Can you add implementation of sign in widgets? Do you clear your values of username/password/user ? Jul 13, 2017 at 11:54
  • Also you can check implementation of signOut here . It looks ok Jul 13, 2017 at 11:56
  • @Mogol I have included both the login page and the login method. I am not sure of this, but I am trying to set FirebaseAuth.instance.currentUser.* to null values whenever I call my login page, but it seems not to work since there is no setters for these values. Jul 13, 2017 at 12:22
  • 1
    google_sign_in is separate plugin, try to add GoogleSignIn.signOut() Jul 13, 2017 at 12:38
  • @Mogol I believe this is not valid in flutter, also I believe it should be done through the Firebase authentication. Jul 13, 2017 at 12:50

9 Answers 9

89

Firebase auth's signOut method is asynchronous. You should make your _signOut method async.

Future<void> _signOut() async {
  await FirebaseAuth.instance.signOut();
}

so that the call to runApp occurs after the user is signed out.

You should also call _googleSignIn.signOut() when logging out if you want signIn to present the user with an authentication dialog instead of silently and automatically re-using the current Google user.

6
  • Please check the final section I have added the async implementation as suggested, however, I do not seem to get it to work correctly. Jul 13, 2017 at 17:39
  • 2
    I do not see you calling signOut on the Google user yet, only the Firebase one. I updated my answer to suggest this. Jul 14, 2017 at 13:08
  • 7
    Thank you very much, this is working. I thought of the same thing that I might need to sign out from google as well. To my understanding that Firebase should handle all of this, otherwise what is the point from including Firebase authentication if I have to sign in and out from each network (google, facebook..) separately, can you clarify this for me please ? Jul 14, 2017 at 15:32
  • 2
    I do have this question.. If my app supports, lets say Google and Facebook, should I sign-in/sing-out individually?
    – Purus
    Feb 26, 2018 at 15:53
  • 2
    I tried _googleSignIn.signOut() while logging out but still, the user is not presented with an authentication dialog. Any idea what could be the reason? Mar 22, 2021 at 4:50
5

You need to have an Instances of FirebaseAuth

  final FirebaseAuth _firebaseAuth = FirebaseAuth.instance;

And Then

  _signOut() async {
    await _firebaseAuth.signOut();
   }
5

Most demos I've looked at only logout of Firebase using a command like _auth.signOut();

This doesn't appear to exist anymore (see Collin's reply above):

_googleSignIn.signOut()

So, I had to use this one method to signout/logout of Google.

_googleSignIn.disconnect();
5

Declare a Future method to call logout function and redirect your page when logout is finished:

Future logout() async {
await _firebaseAuth.signOut().then((value) => Navigator.of(context).pushAndRemoveUntil(MaterialPageRoute(builder: (context) => LoginPage()),(route) => false))); 
}
3

First create an instance of FirebaseAuth like so

 FirebaseAuth auth = FirebaseAuth.instance;

Then add this to either your logout button or any means you wish to use for the logout.

signOut() async {
    await auth.signOut();
  }

You can also create a function and then call the signOut within your button like so

import 'package:flutter/material.dart';

class SignOut extends StatefulWidget {
  @override
  _ SignOut State createState() => _ SignOut State();
}

class _ SignOut State extends State< SignOut > {

     FirebaseAuth auth = FirebaseAuth.instance;
    
      signOut() async {
        await _firebaseAuth.signOut();
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          backgroundColor: Colors.white,
          body: Center(
            child: Container(
              child: RaisedButton(
                onPressed: () {
                  signOut();
                },
    
              )
            ),
          ),
        );
      }
    }

You decide.

2
  • What is the reason for using a StatefulWidget?
    – ingdc
    Apr 2, 2023 at 14:13
  • You can do without the StatefulWidget and it will still work Jun 11, 2023 at 10:59
3

If every answer above is not working, maybe a Page is laying above everything else, then use Navigator.of(context).pop(); to pop the page.

I've searched hours looking for a mistake that wasn't even there just for this small mistake.

1
  • I had to pop twice because I have a splash screen (if it helps someone) - thanks for the hint @Nuqo
    – iOS Flow
    Apr 3, 2022 at 14:33
3

Make sure you Firebase auth and Google signin both hit a logout function

FirebaseAuth.instance.signOut(); // this FirebaseAuth is not a await function so you can skip that 
await GoogleSignIn().signOut(); //For GoogleSignIn
2

you should make your signout function asynchronous

   Future<void> _signOut() async {
  await FirebaseAuth.instance.signOut();
}
0

thats what workd for me

 TextButton(
                  onPressed: () async {
                    final navigator = Navigator.of(context);
                    await CacheHelper.removeData(key: AppConstants.userKey);
                    await GoogleSignIn().signOut();

                    navigator.pushAndRemoveUntil(MaterialPageRoute(
                        builder: (c) => const GoogleAuthScreen()),(route)=>false);
                  },
1
  • As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.
    – Community Bot
    Mar 16, 2023 at 5:20

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.