skip to Main Content

How should one program a Sign In with Twitter feature using firebase_auth and Flutter?

I see a few examples using flutter_twitter_login or flutter_twitter, however they use a now Deprecated API and folks complain about Apple Store Rejection.

Firebase Auth offers a TwitterAuthProvider, but the following code remains incomplete:

final AuthCredential credential = TwitterAuthProvider.getCredential(
  authToken: twitterAccessToken,
  authTokenSecret: twitterAccessTokenSecret,
);
final AuthResult result = await auth.signInWithCredential(credential);

4

Answers


  1. Chosen as BEST ANSWER

    I was able to solve this using 3 resources:

    1. The Flutter Facebook Sign In (with Firebase) in 2020 article
    2. The Log in with Twitter guide
    3. The Dart OAuth1 library

    Ultimately, I was able to completely remove the flutter_twitter package, yet still support Sign in with Twitter.

    Similar to the CustomWebView outlined in the Facebook solution, I created a TwitterLoginScreen like:

    import 'package:firebase_auth/firebase_auth.dart';
    import 'package:flutter/material.dart';
    import 'package:flutter_webview_plugin/flutter_webview_plugin.dart';
    import 'package:oauth1/oauth1.dart';
    
    /// Twitter Login Screen.
    /// See [Log in with Twitter](https://developer.twitter.com/en/docs/basics/authentication/guides/log-in-with-twitter).
    class TwitterLoginScreen extends StatefulWidget {
      final twitterPlatform = Platform(
        'https://api.twitter.com/oauth/request_token', // temporary credentials request
        'https://api.twitter.com/oauth/authorize', // resource owner authorization
        'https://api.twitter.com/oauth/access_token', // token credentials request
        SignatureMethods.hmacSha1, // signature method
      );
    
      final ClientCredentials clientCredentials;
      final String oauthCallbackHandler;
    
      TwitterLoginScreen({
        @required final String consumerKey,
        @required final String consumerSecret,
        @required this.oauthCallbackHandler,
      }) : clientCredentials = ClientCredentials(consumerKey, consumerSecret);
    
      @override
      _TwitterLoginScreenState createState() => _TwitterLoginScreenState();
    }
    
    class _TwitterLoginScreenState extends State<TwitterLoginScreen> {
      final flutterWebviewPlugin = FlutterWebviewPlugin();
    
      Authorization _oauth;
    
      @override
      void initState() {
        super.initState();
    
        // Initialize Twitter OAuth
        _oauth = Authorization(widget.clientCredentials, widget.twitterPlatform);
    
        flutterWebviewPlugin.onUrlChanged.listen((url) {
          // Look for Step 2 callback so that we can move to Step 3.
          if (url.startsWith(widget.oauthCallbackHandler)) {
            final queryParameters = Uri.parse(url).queryParameters;
            final oauthToken = queryParameters['oauth_token'];
            final oauthVerifier = queryParameters['oauth_verifier'];
            if (null != oauthToken && null != oauthVerifier) {
              _twitterLogInFinish(oauthToken, oauthVerifier);
            }
          }
        });
    
        _twitterLogInStart();
      }
    
      @override
      void dispose() {
        flutterWebviewPlugin.dispose();
        super.dispose();
      }
    
      Future<void> _twitterLogInStart() async {
        assert(null != _oauth);
        // Step 1 - Request Token
        final requestTokenResponse =
            await _oauth.requestTemporaryCredentials(widget.oauthCallbackHandler);
        // Step 2 - Redirect to Authorization Page
        final authorizationPage = _oauth.getResourceOwnerAuthorizationURI(
            requestTokenResponse.credentials.token);
        flutterWebviewPlugin.launch(authorizationPage);
      }
    
      Future<void> _twitterLogInFinish(
          String oauthToken, String oauthVerifier) async {
        // Step 3 - Request Access Token
        final tokenCredentialsResponse = await _oauth.requestTokenCredentials(
            Credentials(oauthToken, ''), oauthVerifier);
    
        final result = TwitterAuthProvider.getCredential(
          authToken: tokenCredentialsResponse.credentials.token,
          authTokenSecret: tokenCredentialsResponse.credentials.tokenSecret,
        );
    
        Navigator.pop(context, result);
      }
    
      @override
      Widget build(BuildContext context) {
        return WebviewScaffold(
          appBar: AppBar(title: Text("Twitter Login")),
          url: "https://twitter.com",
        );
      }
    }
    
    

    Then, the AuthCredential result from this screen can be passed to FirebaseAuth.signInWithCredential.


  2. They have shared a common sample in the home page itself, only the ‘sign in provider’ changes, rest is same for all (google, fb and twitter). the result has a user property which will return the user details, check with the below code

    final AuthCredential credential = TwitterAuthProvider.getCredential(
      authToken: twitterAccessToken,
      authTokenSecret: twitterAccessTokenSecret,
    );
    final AuthResult result = await auth.signInWithCredential(credential);
    final FirebaseUser user = result.user;
    print("signed in " + user.displayName);
    
    Login or Signup to reply.
  3. To sign in with Twitter do the following:

     Future<FirebaseUser> loginWithTwitter() async {
      var twitterLogin = new TwitterLogin(
        consumerKey: 'key',
        consumerSecret: 'secretkey',
      );
    
      final TwitterLoginResult result = await twitterLogin.authorize();
    
    switch (result.status) {
      case TwitterLoginStatus.loggedIn:
        var session=result.session;
        final AuthCredential credential= TwitterAuthProvider.getCredential(
          authToken: session.token,
          authTokenSecret: session.secret
        );
        FirebaseUser firebaseUser=(await firebaseAuth.signInWithCredential(credential)).user;
        print("twitter sign in"+firebaseUser.toString());
        break;
      case TwitterLoginStatus.cancelledByUser:
        break;
      case TwitterLoginStatus.error:
        break;
    }
    

    Use twitterlogin and pass the consumer key and consumer secret key, then use the method getCredential() and signInWithCredential to log in.

    Login or Signup to reply.
  4. This worked for me. (Referred from https://firebase.flutter.dev/docs/auth/social#twitter)

    import 'package:twitter_login/twitter_login.dart';
    
    Future<UserCredential> signInWithTwitter() async {
      // Create a TwitterLogin instance
      final twitterLogin = new TwitterLogin(
        apiKey: '<your consumer key>',
        apiSecretKey:' <your consumer secret>',
        redirectURI: '<your_scheme>://'
      );
    
      // Trigger the sign-in flow
      final authResult = await twitterLogin.login();
    
      // Create a credential from the access token
      final twitterAuthCredential = TwitterAuthProvider.credential(
        accessToken: authResult.authToken!,
        secret: authResult.authTokenSecret!,
      );
    
      // Once signed in, return the UserCredential
      return await FirebaseAuth.instance.signInWithCredential(twitterAuthCredential);
    }
    

    This wasn’t working initially for me.

    Things I had to change in order for this to work.

    1. Request for Elevated Permissions in Twitter Developer Portal.
    2. Create a custom scheme (callback URL) and configure the ios/android files accordingly. As given in (https://pub.dev/packages/twitter_login).
    3. Also configure this callback URL in the Twitter dev portal.
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search