はじめに
FlutterでFirebaseのログイン機能を作っていたら、
いつもは問題なく動くはずの signInWithEmailAndPassword
が急にエラーを出すようになりました。
出てきたエラーはこれです。
[firebase_auth/channel-error] "dev.flutter.pigeon.firebase_auth_platform_interface.FirebaseAuthHostApi.signInWithEmailAndPassword".
これは、Flutter(Dart)側から Android/iOS のネイティブ側に signInWithEmailAndPassword を呼び出そうとした際に、Flutterとネイティブ間の通信(channel)が失敗したというエラーです。
このエラーに含まれている「pigeon」は、Flutterとネイティブ(Android/iOS)間の通信を型安全に行うためのコード生成ツールです。
問題の状況
- あるアカウントではログインに失敗する
- 別のアカウントだと問題なくログインできる
- 同じコードなのに、成功したり失敗したり不安定
- 失敗時にはいつもこの
[firebase_auth/channel-error]
が出る
原因と考えられること
結論から言うと、
TextEditingController.text
を入力前に取得してしまっていたことが原因っぽいです。
final emailController = TextEditingController();
// 画面のビルド時など、早いタイミングで.textを取ってしまう
final email = emailController.text;
そのままこの email
を使ってログイン処理をしていました。
なぜハマったのか
-
.text
を取った時点では空文字だったのに気づかず使ってしまう - 空文字のままFirebaseに送られ、認証が失敗する
- ただしエラーは
invalid-credential
ではなくchannel-error
が返ってきて、原因がわかりにくい - タイミングやユーザー操作によっては成功もするので、再現が安定しない
対策
-
.text
はボタンを押すなど、入力が終わったタイミングで取得する - 取得後に
.isEmpty
で空文字チェックをして、空なら処理を中断する - 謎のエラーが出たら、まずUIから正しい値が取れているかログを確認する
初歩的なミスではありましたが、エラーメッセージから原因を特定しづらく、
しかも firebase_auth
周りのエラーだったため、「設定ミスでは?」と疑って構成を一から見直したりしてしまいました。
さらに、発生する時としない時があるため再現性も低く、原因の特定にかなり時間を取られてしまいました。
同じようなエラーで悩む方の参考になればうれしいです。