How to sign out of Microsoft and Github with Flutter Firebase

124 views Asked by At

I can't seem to force a sign out of Github or Microsoft they way I do for Google. With the help of the google_sign_in package.

  Future<GoogleSignInAccount?> _signOutWithGoogle() async {
    return Chain.capture(() async {
      try {
        return await GoogleSignIn().signOut();
      } on Exception catch (error, stackTrace) {
        final terseStacktrace = Chain.forTrace(stackTrace).terse;

        logger.e(
          "GoogleSignOutException",
          error: error,
          stackTrace: terseStacktrace,
        );

        rethrow;
      }
    });
  }

    Future<Result<void, LogOutFailure>> signOut() async {
    try {
      if (_auth.currentUser?.providerData.first.providerId == "google.com") {
        await _signOutWithGoogle();
      }

      await _auth.signOut();

      return const Result.success(null);
    } catch (_) {
      return const Result.error(LogOutFailure());
    }
  }

Without a signout from the package, I'll be automatically logged in as the previous credential I used and I won't be able to change it.

The same issue persists for Microsoft and Github sign ins.

import 'package:firebase_auth/firebase_auth.dart';

    Future<UserCredential> signInWithMicrosoft() async {
      final microsoftProvider = MicrosoftAuthProvider();
      if (kIsWeb) {
        await FirebaseAuth.instance.signInWithPopup(microsoftProvider);
      } else {
        await FirebaseAuth.instance.signInWithProvider(microsoftProvider);
      }
    }

Calling _auth.signOut() isn't enough since it only signs out the firebase user not the github or microsoft user.

Is there a package or implementation I can use to solve this?

1

There are 1 answers

3
Keyboard Corporation On
  1. For Microsoft, you can use the logoutRedirect method from the Microsoft Authentication Library (MSAL). This method clears the local cache of user tokens and redirects the window to the server signout page. This is a more comprehensive signout solution.
Future<UserCredential> signOutWithMicrosoft() async {
 final microsoftProvider = MicrosoftAuthProvider();
 if (kIsWeb) {
   await FirebaseAuth.instance.signInWithPopup(microsoftProvider);
 } else {
   await FirebaseAuth.instance.signInWithProvider(microsoftProvider);
 }
 // Use MSAL's logoutRedirect method here
}
  1. For GitHub, there isn't a direct method to sign out the user. One workaround is to navigate to https://github.com/logout to log out from GitHub. However, this is not a programmatic solution. You may want to consider using a webview to navigate to this URL and then close the webview.
Future<void> _signOutWithGithub() async {
 final Completer<WebViewController> _controller = Completer<WebViewController>();
 await Navigator.push(
   context,
   MaterialPageRoute(builder: (context) {
     return WebView(
       initialUrl: 'https://github.com/logout',
       javascriptMode: JavascriptMode.unrestricted,
       onWebViewCreated: (WebViewController webViewController) {
         _controller.complete(webViewController);
       },
       navigationDelegate: (NavigationRequest request) {
         if (request.url.startsWith('https://github.com/login')) {
           Navigator.pop(context);
           return NavigationDecision.prevent;
         }
         return NavigationDecision.navigate;
       },
     );
   }),
 );
}

Then, remember to call these methods in your signOut method:

Future<Result<void, LogOutFailure>> signOut() async {
 try {
   if (_auth.currentUser?.providerData.first.providerId == "microsoft.com") {
     await signOutWithMicrosoft();
   } else if (_auth.currentUser?.providerData.first.providerId == "GitHub.com") {
    await _signOutWithGithub();