Dynamic Linksが使えなくなるけど、メール認証新規登録はしたい【Flutter×Firebase】
Dynamic Linksが使えなくなる!
Firebase Dynamic Links は非推奨となっており、このリンクがまだ使用されていないプロジェクトでは採用しないでください。サービスは 2025 年 8 月 25 日に廃止されます
ということで、Dynamic Links
を使わずにメール認証新規登録をする方法を模索してみました
ちなみに、Firebase Authentication
のDynamic Links
は引き続き使えるのがミソです
Q. Firebase Authentication でのみ Dynamic Links を使用しています。Firebase Authentication のメールリンク認証は引き続き機能しますか?
はい。Firebase Authentication を使用したメールリンク認証は引き続き機能します。 Firebase Authentication は現在、Firebase Dynamic Links を使用して Authentication リンクをカスタマイズしていますが、Firebase Dynamic Links サービスが終了した後もこの機能が引き続き動作するように、更新を提供いたします。
sendSignInLinkToEmailの謎挙動
パスワードリセットやパスワード変更、currentUserがある場合のメール認証(currentUser.sendEmailVerification
)はWeb上で完結する機能がFirebaseに用意されている。
だから用意されているメソッドを叩くだけでいい。
でもなぜか、sendSignInLinkToEmail
で送信されるURLはDynamic Linksだし、Web上で処理してくれない(ローディングして、なんか処理してる風だけどなにもしてない?mode=signinになってるのになにもしないという謎)
そのため、処理は自分で書く必要がある。
公式でもアプリで処理してね、とのこと。
Firebase Authentication は、Firebase Dynamic Links を使用してモバイル デバイスにメールリンクを送信します。モバイルアプリ経由でログインを行う場合、リンクの受信を検出し、ディープリンクを解析してログインを完了するようにアプリを構成する必要があります。
というわけで進めます。
Firebase AuthenticationのDynamic Linksは引き続き使えるのがミソです
上記ですがFirebaseサポートに問い合わせたところ、おそらく間違いで"メール認証機能"のみが引き続き使えるだけだと思います。案内されたリンクはこちらでsendSignInWithEmail()で送信されるすべてのメールリンクは終了日以降404が返されるようです。
おそらく、移行後のsendSignInWithEmail()に相当するメソッドで送信するメールにはDynamic linksではない型式のリンクが付与されるようになるということだと思います。
また、代替案としてこちらが提示されておりました。補足としてコメント失礼しました。
サポートにご連絡いただき、ありがとうございます。
いままでアプリで処理していたものが、2025年8月25日以降はWeb上でメール認証が行われるイメージなのでしょうか?
設定はこれだけ
とりあえず、これの通りやればいいのですが、最低限忘れがちなのをメモします。
Firebase コンソールでDynamic Linksを有効化する
Dynamic Linksは使えなくなるのですが、なぜかDynamic Linksを有効にしないとそもそもメール認証時にエラーが返ってきます。謎です。
FirebaseにApp Store IDとチーム IDを設定する
Firebaseのプロジェクトの設定 > 全般 > マイアプリ > Appleアプリ
の設定を忘れないように。
デフォルトで設定不要だけど必要。
もちろんApple Store IDはApple Store Connectからアプリ作らないとダメ。
info.plistでFirebaseDeepLinkPasteboardRetrievalEnabledをONにしない
変な挙動になります。OFFにするかそもそも書かなくてOK!
作ったDynamic LinksをAssociated Domainsにいれる
コードを書く
Flutterを書いていきます
uni_linksを入れる
これ!
コードはこれだけ!
// importは省略
final FirebaseAuth _auth = Firebase.auth;
StreamSubscription? _uniLinksListener;
Future<void> signupWithEmail({required String email}) async {
try {
final actionCodeSetting = ActionCodeSettings(
url: {ACTION_CODE_URL}, // Webに飛んだ場合の最終リダイレクトURL(アプリのみで認証するなら、スマホで開いてくださいとかアラーとするのもあり?)
iOSBundleId: {IOS_BUNDLE_ID},
handleCodeInApp: true,
androidPackageName: {ANDROID_PACKAGE_NAME},
androidInstallApp: true,
androidMinimumVersion: '12',
);
await _auth.sendSignInLinkToEmail(email: email, actionCodeSettings: actionCodeSetting);
_uniLinksListener = linkStream.listen((uri) async {
try {
await _auth.signInWithEmailLink(email: email, emailLink: link);
if (_uniLinksListener != null) {
_uniLinksListener?.cancel();
_uniLinksListener = null;
}
} on AppException {
rethrow;
}
});
} on AppException {
rethrow;
}
}
ちょっと解説
パスワード認証もしたい場合は?
もちろんできます。
メール認証のユーザーにパスワードでもログインするようにします。
上の方法でユーザーを作ったら、以下を使ってパスワードありのユーザーにしましょう。
パスワード設定
await currentUser.updatePassword(password);
await currentUser.reauthenticateWithCredential(
EmailAuthProvider.credential(
email: currentUser!.email!, password: password),
);
パスワードが登録されているユーザーかをチェック
final signInMethods = await FirebaseAuth.instance.fetchSignInMethodsForEmail(currentUser!.email!);
return signInMethods.contains(EmailAuthProvider.EMAIL_PASSWORD_SIGN_IN_METHOD);