FlutterFire(FlutterでのFirebaseファミリー)がアップデートし、複数のFirebaseパッケージを使用していたので対応しなければならなくなりました。
アップデートすべきパッケージが多かったのと、破壊的変更があるとのことで身構えていました。
しかし、丁寧な公式ドキュメントもあり、僕の場合は問題なく追従することができました。
公式ドキュメント:Migration Guide | FlutterFire
なので、☝️のマイグレーションガイドを見るのが一番確実で分かりやすいと思います!
しかし、今回記録を取りながら対応したので備忘録としてここに残すことにしました。
環境
- Flutter: 1.20.2
- Xcode: 10.15
- Visual Studio Code: 1.48.0
各パッケージのアップデート
どのパッケージをどのバージョンにアップデートすべきかはマイグレーションガイドにハッキリと書かれているのでそれに合わせるだけでした。
一応、僕の環境ではこんな感じ
※monoさんの firestore_ref
を使わせていただいているので併せてアップデートしています。
Androidのbuild.gradleを編集
android/build.gradle
のcom.google.gms:google-services
のバージョンを最新化するように書いてあったため、3.2.1 を 4.3.3に修正しました。
dependencies {
classpath 'com.android.tools.build:gradle:3.6.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'com.google.gms:google-services:4.3.3' // ここを変更!
classpath 'io.fabric.tools:gradle:1.28.0' // Crashlytics
}
Firebaseの初期化処理を追加
Firebaseの各サービスを使う前にFirebase.initializeApp()
を実行しておく必要があります。
僕は以下のようにrunApp(Widget app)
前に、(非同期なので)await で実行するようにしました。
void main() async {
WidgetsFlutterBinding.ensureInitialized();
// Firebaseの各サービスを使う前に初期化を済ませておく必要がある
await Firebase.initializeApp();
runApp(const App());
}
monoさんに教えていただきましたが、公式のexampleでもそうしているようです。
それが一番良いと思います( ´・‿・`)https://t.co/0vfo0GD0QM とかもそうなってますね( ´・‿・`)
— mono (@_mono) August 21, 2020
実装コードの修正
Firestore
Firestoreのインスタンスを取得する時の書き方が変わった。
// Before
Firestore.instance;
// After
FirebaseFirestore.instance;
スナップショット等のdata
がゲッターではなくメソッドになった。
// Before
snapshot.data;
// After
snapshot.data();
スナップショット等から取得するdocumentID
がid
という名前になった。
// Before
snapshot.documentID;
// After
snapshot.id;
アップデートのメソッド名が短くなった。
// Before
updateData(Map<String, dynamic> data);
// After
update(Map<String, dynamic> data);
DocumentReference
を取得するメソッド名が短くなった。
// Before
document([String path]);
// After
doc([String path]);
List<QueryDocumentSnapshot>
を取得するゲッター名が短くなった。
// Before
List<QueryDocumentSnapshot> get documents
// After
List<QueryDocumentSnapshot> get docs
set の merge
パラメータがSetOptionsを使うようになった。
// Before
setData(Map<String, dynamic> data, [Bool merge])
// After
set(Map<String, dynamic> data, [SetOptions options])
// e.g.
.set(
data,
SetOptions(merge: true),
)
Authentication
サインイン中ユーザーを取得するメソッドがゲッターになり、非同期ではなくなった。
// Before
await FirebaseAuth.instance.currentUser();
// After
FirebaseAuth.instance.currentUser;
一見、非同期ではなくなり嬉しいのですが、注意点もあるそうです。僕もアプリ起動時にサインイン状態かを判定しているので、ここの挙動は注意深く見ていきたいと思います🙏
扱いにくいという意見をちょくちょく見かけるWebのSDKに合わせられてしまったので、「便利になって嬉しい」と単純に書き換えると危険なことがある。
— mono (@_mono) August 19, 2020
例えば起動直後にアクセスしてnullだった場合、未ログインなのかまだ内部的な更新処理が終わってないだけなのか分からない。https://t.co/oYXxS4GlDr https://t.co/2JMFtQFxFi pic.twitter.com/yu1b8RVOR4
ユーザーの型名がUser
になった。
// Before
FirebaseUser
// After
User
onAuthStateChanged
ゲッターがauthStateChanges
メソッドになった。
// Before
onAuthStateChanged;
// After
authStateChanges();
userChanges
が追加された。
https://pub.dev/documentation/firebase_auth/latest/firebase_auth/FirebaseAuth/userChanges.html
onAuthStateChanged
がユーザーのサインイン状態(サインインやサインアウトなど)の変更についてだけ通知するのに対してidTokenChanges
の機能も含んだスーパーセットということでしょうかね?
// 使用例
_auth.userChanges().listen((user) {
state = user;
});
AuthResultの型名が変更された。
// Before
AuthResult
// After
UserCredential
OAuthProvider
が引数名なしになった。
// Before
OAuthProvider({String providerId})
// After
OAuthProvider(String providerId)
getCredential
のメソッド名からget
がなくなった。
// Before
getCredential({String accessToken, String idToken, String rawNonce})
// After
credential({String providerId})
unlinkFromProvider
のメソッド名が短くなった。
// Before
unlinkFromProvider(String providerId)
// After
unlink(String providerId)
FirestoreWeb も FirebaseFirestoreWeb に
// Before
FirestoreWeb
// After
FirebaseFirestoreWeb
以上は僕が対応必要だったところだけ書き残しただけなので、実際にはもっとたくさんの変更があります。
Migration Guide | FlutterFireにすべて書いてありますので上から順に対応していくのが良いかと思います!
ご閲覧ありがとうございました!