Open10

Firebase Authの認証メールをFDLからHostingベースに切り替えたらiOSで「The operation is not valid」が出た。

ohtsukiohtsuki

Firebase Dynamic Links サ終するってよ。認証メールリンクも移行しないと機能しなくなるってよ。

前提

  • FlutterでAndroid / iOSアプリをリリースしてる。
  • Firebase Authでメールリンクを使用していて、Dynamic Links(以下FDL)を内部で使っている。
  • FDLはディープリンクとしても使用しており、こちらはBranch.ioへ切り替え作業を終えている。
    • Branchの設定や、ディープリンクを受け取ってナビゲーションの実装は割愛します。
ohtsukiohtsuki

参考にした資料

これそのまま手順通りに対応すると、今回の私のPJのケースではタイトルのエラーに悩まされることになった。これはFDLで使っていたリンクをHostingでも継承して使いたいよって人にはマッチする。

ただ、今回はアプリに戻ってくるcontinueUrlにBranch.ioのリンクを使いたかったので、このURLの手順だといらないステップもあった。

ohtsukiohtsuki
  1. Firebase Hosting ドメインをアプリに関連付けられたドメインにリンクします。

選択したドメインをアプリリンクの関連ドメインとして構成する必要があります。アプリで利用資格を設> 定するには、Xcode でターゲットの [Signing & Capabilities] タブを開き、前の手順で作成した Firebase > Hosting ドメインを Associated Domains 機能に追加します。デフォルトの Firebase Hosting ドメインを> 使用している場合は、applinks:PROJECT_ID.firebaseapp.com になります。

詳細については、Apple のドキュメント サイトで関連付けられたドメインのサポートをご覧ください。

関連するドメイン ファイルがすべての Firebase Hosting ドメインにデプロイされています。アクセスするには、PROJECT_ID.firebaseapp.com/.well-known/apple-app-site-association に移動します。 この AASA ファイルは上書きできます。詳細については、ユニバーサル リンクの構成ファイルを作成してホストするをご覧ください。

このステップが要らなかった。ステップ1だぞ。
FDLが使われていた時は、FDLのドメインをここに指定する必要があったのですが、単純思考でHostingのドメインに差し替えたれっとしたことが仇となった。いらないっすこれ。

ohtsukiohtsuki

新規でメールとパスワードアカウント作成 > 認証メール送るところ。
私のPJではBranchのサブドメインがassociated domainに入ってればOKなので、深く考えずにHosingのドメインまでiOS側に設定してしまったため謎い動きになったという。

      await user.sendEmailVerification(
        ActionCodeSettings(
          url: '$dynamicLinkDomain/$linkPath',
        ),
      );

      await user.sendEmailVerification(
        ActionCodeSettings(
          url: '$branchLinkDomain/$linkPath',
        ),
      );
ohtsukiohtsuki

原因となった設定を削除。
これでFDLの時と全く同じ正しい動きになった。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>aps-environment</key>
	<string>development</string>
	<key>com.apple.developer.applesignin</key>
	<array>
		<string>Default</string>
	</array>
	<key>com.apple.developer.associated-domains</key>
	<array>
		<string>applinks:${DYNAMIC_LINK_DOMAIN}</string>
		<string>applinks:${HOSTING_DOMAIN}</string> ❌いらない、ここを消したらエラーが消えて正しく機能したした。
	</array>
</dict>
</plist>
ohtsukiohtsuki

Admin SDKでこれだけ実行しておけばとりあえずOK?
コンソールから気軽に切り替えられるようにしてほしい。

const updateRequest = {
mobileLinksConfig: {
    domain: 'HOSTING_DOMAIN'
}
}
const updateProjectConfig = () => {
projectConfigManager.updateProjectConfig(updateRequest)
.then((response) => {
    // updated project config
}).catch((error) => {
    console.log('Error updating the project:', error);
});
}
ohtsukiohtsuki

ぼやき

AASAを書き換えてはFirebase Hostingにデプロイする、AppleのCDNが切り替わる(大体1hかかる)まで待って動作確認するの無限ループをしてしまった。久々によく考えたら分かりそうなところでどん詰まりしたので記録しました。

ドキュメントがトラップすぎた。

ohtsukiohtsuki

一晩置いたらまたタイトルエラー出るようになった、なぜだ。
まだクローズできなさそうだ。

原因ぽいやつ
okだった認証リンク
https://PROJECT_ID.firebaseapp.com//auth/links?link=https://PROJECT_ID.firebaseapp.com//auth/action?apiKey%API_KEY%26mode%3DverifyEmail%26oobCode%OOBCODE%26continueUrl%3Dhttps://BRANCH_DOMAIN/emailLink%26lang%3Dja

ng
https:/PROJECT_IDfirebaseapp.com//auth/action?mode=verifyEmail&oobCode=OOBCODE&apiKey=API_KEY&continueUrl=https%3A%2F%2FPROJECT_ID.firebaseapp.com%2F%2Fauth%2Flinks%3Flink%3Dhttps%3A%2F%2FBRANCH_DOMAIN%2FemailLink&lang=ja

ngの方はcontinueUrlがネストしている。あと、なんでこれも違うのか謎い。この辺の設定触ってないんだけどな。ActionCodeSettingsのURLか。

/__auth/links?
__/auth/action?

ohtsukiohtsuki

理解したぞ、これでOKな認証リンクになった。
ガチャガチャ操作していて消したりなんだりしてた。FDLの時はなくても動いてた。

      await user.sendEmailVerification(
        ActionCodeSettings(
          url: '$branchLinkDomain/$linkPath',
          handleCodeInApp: true, ✅これ
        ),
      );

ドキュメントには確かtrueにしとけって書いてあったかもしれん。うっかり。しかしわかりづらい。

The default is false. When true, the action code link will be sent as a Universal Link or Android App Link and will be opened by the app if installed.

ohtsukiohtsuki

結論:

  • 別サービスのディープリンクに移行するなら、認証リンクのFirebae Hostingのドメインを関連するドメインに設定しなくても良い。
  • ActionCodeSettingsのhandleCodeInAppをtrueにする。

ドキュメントがわかりづらいし、そもそもバックエンドでupdateProjectConfigを実行する謎い移行プロセス。解せなかったのでHostingドメインのデフォルトAASAを空にしたりもした。

もし同じ状況で困っている方がいたら、ヒントになりますように🙏

ここでもドキュメント解せぬ民たちがいて、心強かった。
https://github.com/firebase/flutterfire/issues/16946