【Flutter】FirebaseでTwitter認証(Auth)のやり方まとめ【スクショ・ソースあり】

どーも、ぐるたか@guru_takaです。

Flutter製のアプリに、FirebaseのAuth機能を追加してみます。今回はtwitter認証の導入です!

Firebaseの初期設定は完了していること前提で進めていきます。まだの方は以下の記事を参考にしてみてください!

iOS13とAndroidXにも対応。実際に起きたエラーと対処方法も最後に記しておきます。

完成図

完成アプリはこちら!



ログイン完了すると、Firebase側でユーザー登録されます!

さっそくやり方を紹介していきます。

開発環境
  • Flutter:1.9.1
  • Android:AndroidX
  • iOS:iOS13

事前準備

Twitter APIの登録と承認

Twitter APIを使うため、アカウント申請、そしてTwitter APIの認証コードの取得が必須です。まだの方は、以下の記事を参考に登録してみて下さい!

私がこちらの記事に従ってやったら、15分くらいでTwitter APIを使えるようになりました。
参考 Twitter API 登録 (アカウント申請方法) から承認されるまでの手順まとめQiita

Firebaseの準備

Twitter APIをFirebase側に登録します。やり方はこちら!

まずTwitter Developerで申請したtwitter APIをコピーします。

その後に、FirebaseのTwitter Authの設定にはりつければOK!

コールバックURLは次のステップで使うのでコピーしておきましょう。

TwitterのDeveloperの設定

続いて、TwitterのDeveloperに登録したAppの設定をしていきます。

まずSign in with Twitterの項目にチェックします。そして、Callback URLに以下3つを入力してください。

  • Firebaseで取得したコールバックURL
  • twitterkit-CONSUMERKEY://
  • twittersdk://

CONSUMERKEYはTwitter APIです。もしTwitter APIが123456789なら、twitterkit-123456789://となります!

iOSの設定

iOSの設定ファイルmy_project/ios/Runner/Info.plistに以下を追記します。

Info.plist
<key>CFBundleURLTypes</key>
<array>
  <dict>
    <key>CFBundleURLSchemes</key>
    <array>
      <!-- もし consumerKeyが123456789なら、twitterkit-123456789となる-->
      <string>twitterkit-<consumerKey></string>
    </array>
  </dict>
</array>
<key>LSApplicationQueriesSchemes</key>
<array>
    <string>twitter</string>
    <string>twitterauth</string>
</array>

パッケージの導入

firebase_auth, flutter_twitter_loginのパッケージをインストールします。バージョンは公式でチェックしましょう。

まずは、pubspec.yamlに以下を追記します。

pubspec.yaml
dependencies:
  firebase_auth: ^0.14.0+5
  flutter_twitter_login: ^1.1.0

その後に、コマンドラインで以下コードを叩き、インストールします。

コマンドライン
$ flutter pub get
参考 firebase_auth pluginpub.dev | 公式 参考 flutter_twitter_loginpub.dev | 公式

ソース

ソースを紹介します。2019/10/25時点、Pixel3a(AndroidX)で動いていますが、iPad(iOS13)はビルド失敗などエラーがでるので、対応方法を後述します。

signInWithTwitter関数とsignOutTwitter関数がGoogleのAuth認証に大きく関係しています。

コメントに概略を記載しているので、チェックしてみて下さい!

main.dart
import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter_twitter_login/flutter_twitter_login.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'auth sample',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: AuthPage(
        title: 'Auth Sample with Firebase',
      ),
    );
  }
}

class AuthPage extends StatefulWidget {
  AuthPage({
    Key key,
    this.title,
  }) : super(
          key: key,
        );

  final String title;

  @override
  _AuthPageState createState() => _AuthPageState();
}

class _AuthPageState extends State {
  final FirebaseAuth _auth = FirebaseAuth.instance;
  
  // APIキーを入力
  final TwitterLogin twitterLogin = TwitterLogin(
    consumerKey: consumerKey,
    consumerSecret: secretkey,
  );

  bool logined = false;

  void login() {
    setState(() {
      logined = true;
    });
  }

  void logout() {
    setState(() {
      logined = false;
    });
  }

  Future signInWithTwitter() async {
    // twitter認証の許可画面が出現
    final TwitterLoginResult result = await twitterLogin.authorize();

    //Firebaseのユーザー情報にアクセス & 情報の登録 & 取得
    final AuthCredential credential = TwitterAuthProvider.getCredential(
      authToken: result.session.token,
      authTokenSecret: result.session.secret,
    );

    //Firebaseのuser id取得
    final FirebaseUser user =
        (await _auth.signInWithCredential(credential)).user;

    assert(!user.isAnonymous);
    assert(await user.getIdToken() != null);

    final FirebaseUser currentUser = await _auth.currentUser();
    assert(user.uid == currentUser.uid);

    login();
  }

  void signOutTwitter() async {
    await twitterLogin.logOut();
    logout();
    print("User Sign Out Twittter");
  }

  @override
  Widget build(BuildContext context) {
    Widget logoutText = Text("ログアウト中");
    Widget loginText = Text("ログイン中");

    Widget loginBtnTwitter = RaisedButton(
      child: Text("Sign in with Twitter"),
      color: Color(0xFF1DA1F2),
      textColor: Colors.white,
      onPressed: signInWithTwitter,
    );
    Widget logoutBtnTwitter = RaisedButton(
      child: Text("Sign out with Twitter"),
      color: Color(0xFF1DA1F2),
      textColor: Colors.white,
      onPressed: signOutTwitter,
    );

    return Scaffold(
      appBar: AppBar(
        centerTitle: true,
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            logined ? loginText : logoutText,
            logined ? logoutBtnTwitter : loginBtnTwitter,
          ],
        ),
      ),
    );
  }
}

Githubにログイン機能(Google・Twitter・Facebook)のサンプルソースを公開しているので、気になる方は参考にしてみて下さい!
参考 gurutaka/flutter_firebase_authGithub

Twitter認証のエラー対応

私がTwitter認証で行き詰まったエラーを載せていきます。iOS13の対応もありますので、ぜひチェックしてみて下さい!

Androidでクラッシュする問題

様々なパッケージの相性の問題かもしれませんが、現在開発中のアプリで何故か、Twitter認証の画面を開いて許可をタップすると、Androidが必ずクラッシュする問題がありました。

firebase_authが悪さをしているようで、Githubのissueに解決策あり!

まず、Android Studioで以下のディレクトリ先にあるFirebaseAuthPlugin.javaを開きます。

そして、以下のコードをコメントアウトすると、クラッシュしなくなりました!

FirebaseAuthPlugin.java
 // additionalUserInfoMap.put("profile", info.getProfile());
参考 firebase_auth Android crash when using the Github AuthProvider #37681Github

iOS13のエラー対応

iOS13が曲者で、半日くらい溶かしました…。

2019/10/25の時点では、issueなどの議論をみる限り、iOS13だとエラーがでるみたいです。

追々公式で対応するかもしれませんが、現地点でビルドまで完了する方法を紹介します。

STEP.1
iOSでビルドすると、pod installでエラーがでると思います。

Error output from CocoaPods:

WARNING: CocoaPods requires your terminal to be using UTF-8 encoding.
Consider adding the following to ~/.profile:
export LANG=en_US.UTF-8

[!] Automatically assigning platform `ios` with version `8.0` on target `Runner` because no platform was specified. Please specify a platform for this target in your Podfile. See `https://guides.cocoapods.org/syntax/podfile.html#platform`.
Error running pod install

この対応方法は以下のとおりです。

まずはビルド結果をクリアにします。

コマンドライン
$ flutter clean

その後に、podfile.lockを削除してください。

最後に、Podfileの4行目くたいに# platform :ios, '9.0'と書かれているので、以下のように修正してコメントアウトを外しましょう!

Podfile
platform :ios, '11.0'

これで再ビルドすると、pod installのエラーは出なくなります!

STEP.2
パッケージをGithubからクローン
これで一安心かと思いきや、またエラーが出ます。
エラー
fatal error: 'TwitterKit/TwitterKit.h' file not found

この問題はissueで議論されています。
参考 iOS example fails with error in emulator #9roughike/flutter_twitter_login | Github

結局、海外の方がForkしてissueを解決したリポジトリがあったので、クローンして解決しました。
参考 eudangeld/flutter_twitter_loginGithub

pubspec.yaml
  # flutter_twitter_login: ^1.1.0
  flutter_twitter_login:
    git:
      url: git://github.com/eudangeld/flutter_twitter_login.git

パッケージを再導入して、ビルドすると、iOS13でも動くようになります!

$ flutter pub get
MEMO
Githubで直接クローンしたものでも、Androidで正常に動いています。

参考リンク

参考 eudangeld/flutter_twitter_loginGithub 参考 Flutter+Firebase — Authenticate with TwitterMedium

その他の認証方法の記事

【Flutter】FirebaseでGoogleのAuth認証をガチ丁寧に紹介【スクショ・ソースあり】 【Flutter】FirebaseでFacebook認証(Auth)のやり方まとめ【スクショ・ソースあり】

コメントを残す