FlutterでFirebaseAuthentication使ってTwitterログインしてみる
タイトルの通り。
10月からFlutter触ろうと思ってたので、試しにログイン処理など作ってみました。
ネットを徘徊してると、ログインだけで完結してるものや、Googleログインの情報はよく見かけたんですが、何故かTwitterログインの情報が少なかったので、Twitterログインで試しています。
あと、ログインの状態管理に ChangeNotifier
と Provider
を利用しました。
Flutterでは状態管理の方法が色々あるようです。
アプリの規模やユースケースによって方法を考えればいいのかなと思いますが、そこまで正直わかってない。。。
まずは第一歩というところで、公式ドキュメントのやり方を参考にこの方法でやってみました。
ちょいちょい耳にはさむBLoCは、イメージは分かるんですけどお作法とかまだよく分かってません。
Flutter is ?
AndroidとiOSのアプリをDartで書けるUIツール。
各パーツや画面をWidgetとして定義して、それを組み合わせてUIを作っていくというのはコンポーネント指向に近いのかなと思うなどしています。
Widget単位で再構築するので処理速度も速いとかなんとか。
ただ、状態の持たせ方によっては不要なビルドが走りまくってパフォーマンスがガタ落ちするとも聞いたので、設計は大事。
あと、ホットリロードがいい感じです。
Flutterの環境構築
公式ドキュメントの手順通りに構築を進めていって、特に躓くところはなかったです。
SDK落としてきてPATH通して flutter doctor
で診察して、足りないものを追加するという流れを繰り返します。
コードなど
ログイン処理と、状態管理の確認をしたかったので
・ログイン画面
・ログイン状態によりメッセージが変化する画面
の2画面の構成です。
パッケージのバージョンによってちょちょいエラーが出てたので、それは後述します。
Firebase
Firebase の公式ドキュメント通りに進めます。
Firebase Authentication を利用するので、これ用のプロジェクトを新たに追加してTwitter認証を有効にしておきます。
プロジェクトにアプリを追加するんですが、今回は AndroidApp で試しました。
「google-services.json をダウンロードしてプロジェクトに追加してな」と言われるので、その通りに。
Twitter の Developer アカウントを登録して、App を追加しておきます。
Callback URL
を設定する際に、Firebase Authentication で発行されるURLだけ設定するとエラーになることがあります。
ここらへんのstackoverflowなどを参考に、「twittersdk://」も追加しました。
※Android限定ですかね?
パッケージ周り
Firebase のパッケージのバージョンで、google-services プラグインのバージョンとの互換性なのか分からないですが、一部うまくいかないケースがありました。
色々とバージョンを変えて試してみて、一応この形で落ち着いています。
android/app/build.gradle
buildscript { (省略) dependencies { classpath 'com.android.tools.build:gradle:3.2.1' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" // Add classpath 'com.google.gms:google-services:4.2.0' } ... }
pubspec.yaml
environment: sdk: ">=2.1.0 <3.0.0" dependencies: flutter: sdk: flutter provider: ^3.0.0 firebase_core: ^0.4.0 # add dependency for Firebase Core firebase_auth: ^0.14.0+5 flutter_twitter_login: ^1.1.0
あと、Androidのエミュレータによっては以下の設定も必要になるようです。
android/gradle.properties
android.useAndroidX=true android.enableJetifier=true
ここら辺は触っていって知見を貯めていくしかないかなぁ。。
状態管理について
ChangeNotifier
を継承した AuthModel
にログイン情報を持たせてます。
ログイン・ログアウトのタイミングで AuthModel
の isLogin
と displayName
を変更して、 notifyListeners()
によって状態の変化を通知する流れにしてます。
(( displayName
をセットするタイミングで notifyListeners()
を呼ぶ必要はなかったかな..))
今回は、最上位のWidget(MyApp
)にproviderとして AuthModel
を指定しているので、それにぶら下がっている LoginPage
と NextPage
で AuthModel
の状態を取得できるような形です。
LoginPage
クラスでは、ログイン・ログアウトの処理を実施したタイミングで AuthModel
にログイン状態をセットしています。
login_page.dart
void _twitterLogin() async { ... 省略(ログイン処理を実施) ... // ログイン状態の更新 if (_twitterLoginStatus == TwitterLoginStatus.loggedIn && _currentUser != null) { _authModel.setLoginState(true); _authModel.setDisplayName(_currentUser.displayName); } }
NextPage
クラスでは、 AuthModel
から状態を取得するのに以下のような形でプロバイダから値を取得してます。
これによって、ログイン状態が変化するごとにWidgetがビルドしなおされ、表示されるログイン情報を更新していきます。
next_page.dart
class NextPage extends StatelessWidget { AuthModel _authModel; @override Widget build(BuildContext context) { _authModel = Provider.of<AuthModel>(context); ... 以下略 ... } void setDisplayMessage(){ if(_authModel.isLogin) { _loginStateMessage = "Hi, " + _authModel.displayName; } } }
雑感
割と簡単に書けるなーと思う反面、Dartを知らなすぎるので良い書き方がまだ分かってないので、そこら辺を知っていくともっと楽しくなるんだろうなと思ってます。
Flutterに関しても、コードの構成とかディレクトリ構成とか、気持ちのいい実装の形ってあると思うので、そういうのは色んなプロジェクト見ながら考えていこうかなと。
あとはIonic触った時も思ったんですけど、やっぱライブラリやパッケージのバージョンと、エミュレータに対してはもっと気を配らないといけないなと思いました。
とりあえず今日はここまで。