🐈
【Flutter】Firebase Auth パスワード認証でUIDを指定してユーザーを作成する
Firebase AuthでEmail/パスワードで認証すると、自動でUIDが割り当てられます。UIDはランダムで発行されるものですが、自分で指定したい。なかなかニッチなニーズとは思いますが、その方法を紹介します。(UIDは以下の赤矢印の値)
結論
UIDを後から変更することは難しいため、
以下の手順を踏んで特定のUIDのユーザーを作成します。カスタムトークンでログイン
↓
メールリンク認証
↓
パスワードセット
アプリ側はFlutter, サーバーサイドはGoのコード例で説明していきます。
手順
1. カスタムトークンを作成
早速ですが、アプリ側でカスタムトークンを発行することはできないので、サーバーサイドなどでFirebase Admin SDKを使用して発行します。カスタムトークンの有効期限は1時間です。
token, err := client.CustomToken(ctx, "指定したいUID")
if err != nil {
log.Fatalf("error minting custom token: %v\n", err)
}
2. カスタムトークンでログインする
1.で発行したカスタムトークンをつかってアプリでログインします。
FirebaseAuth.instance.signInWithCustomToken(token);
3. メール認証
2.までの状態だと、Email/パスワードが紐づいていない状態になります。
(一番左がハイフン(-)になっている)
ここからメールリンク認証をすることでメールを紐付けます。
var acs = ActionCodeSettings(
// The link will redirect the user to this URL if the app is not
// installed on their device and the app was not able to be installed.
url: url,
handleCodeInApp: true,
iOSBundleId: "iOSのBundleIdentifier",
androidPackageName: "Androidのパッケージ名",
androidInstallApp: true,
androidMinimumVersion: '24',
);
try {
await FirebaseAuth.instance
.sendSignInLinkToEmail(email: email, actionCodeSettings: acs);
} on FirebaseAuthException catch (e) {
log('Error sending email verification $e');
return;
}
// Store mail to shared preferences
SharedPreferences.getInstance().setString("temp_email", email);
Dynamic Link(サービス終了予定なので、他の方法を調べたらまた記事にします・・・)を使う前提です。
FirebaseDynamicLinks.instance.onLink.listen((dynamicLinkData) {
handle(data: dynamicLinkData);
}).onError((error) {
// Handle errors
});
Future<void> handle({
required PendingDynamicLinkData data,
}) async {
final auth = FirebaseAuth.instance;
final emailLink = data.link.toString();
final emailAuth = await SharedPreferences.getInstance().getString("temp_email");
if (emailAuth != null && auth.isSignInWithEmailLink(emailLink)) {
final authCredential = EmailAuthProvider.credentialWithLink(
email: emailAuth,
emailLink: emailLink.toString(),
);
try {
await auth.currentUser?.linkWithCredential(authCredential);
} catch (e, s) {
log(e.toString(), stackTrace: s);
}
}
}
4. パスワードセット
最後にパスワードをセットします。
FirebaseAuth.instance.currentUser?.updatePassword("newPassword")
これで指定のUIDでEmail/パスワード認証ユーザーの作成を再現できました。
Discussion