Firebaseの関連するユーザデータ削除を簡単に実現してみる【Authentication,Firestore,Functions】
前置き
Firebase Authenticationで、クライアント側から簡単にユーザ登録できるんだから、削除も簡単でしょうと思ってた愚か者のお話です。
ログイン中のユーザインスタンスからdeleteメソッドを叩けばユーザ削除も簡単だよね!やってみよう!
mAuth.getCurrentUser().delete().addOnCompleteListener(task -> {
if (task.isSuccessful()) {
Log.d("DEBUG","Successful to delete user.");
} else {
Log.e("DEBUG", "Failed to delete user.", task.getException());
}
});
2021-03-13 11:04:38.569 6841-6841/com.crabsan.anshare.debug E/DEBUG: Failed to delete user.
com.google.firebase.auth.FirebaseAuthRecentLoginRequiredException: This operation is sensitive and requires recent authentication. Log in again before retrying this request.
at com.google.android.gms.internal.firebase-auth-api.zztt.zza(com.google.firebase:firebase-auth@@20.0.2:22)
at com.google.android.gms.internal.firebase-auth-api.zzvb.zza(com.google.firebase:firebase-auth@@20.0.2:9)
at com.google.android.gms.internal.firebase-auth-api.zzvc.zzk(com.google.firebase:firebase-auth@@20.0.2:1)
上記コードだとエラーに。ログを読むと、ユーザ削除等のセキュリティ上重要な操作には再認証が必要とのこと。
再度ドキュメントを読み直してみると、がっつり書いてましたw
ログ通りの実装に変更するにはSSO毎に別途トークンの取得処理が必要のため、複雑なロジックとなりそうです。
また、その他下記理由から別の方法を取りました。
- ユーザの再認証(トークン取得等)をすれば実現可能だが、例外処理のパターンが増えクライアント側の処理が複雑になる
- Authenticationで管理しているユーザ削除と同時に、Firestore(DB)に保存しているユーザデータも削除したい
- ユーザ削除した履歴も同時に残したい
この記事では、これらを実現するためにしたことをまとめています。
結論
Firebase AuthenticationやFirestoreに登録されたユーザデータを一括で削除するため、下記構成にしてみました。
こちらの構成にすることで以下メリットがありました。
- クライアント側でFirebase Authenticationの再認証が不要
- クライアント側の例外処理が簡易(ここが1番のメリット)
- Backgroundで全ユーザ情報を削除できるため、クライアント側の負担減
- ユーザ削除履歴も処理の流れで生成できる
① 削除するUIDをFirestoreに登録
クライアント側はFirestoreに削除するユーザIDと削除日を書き込む。
これだけです!!
関連データの削除等もFirebase Cloud Functionsに委譲しており、簡単に実装可能です。
// 削除履歴データ生成
final Map<String, Object> deleteData = new HashMap<>();
deleteData.put("uid", uid);
deleteData.put("ctAt", FieldValue.serverTimestamp());
// Firestoreにデータ登録
mFirestore
.collection('deleted_users')
.add(deleteData)
.addOnCompleteListener(mThreadExecutor, task -> {
if (task.isSuccessful()) {
// ユーザ削除完了後の処理
} else {
// ユーザ削除失敗のため、UIへ失敗通知
}
});
{
uid: "xxx"
createdAt: 1615600018000
}
注意点としては、Firestoreのセキュリティールールをしっかり導入しておくこと。
Firestoreの特定コレクションにデータ追加さえすればユーザ削除ができてしまうので、悪用される懸念は当然あります。
自分は以下ルールを設定し、リクエストしたユーザしか自身のデータを追加できない制約を与えています。
- 登録するドキュメントのuidとリクエストのuidが同じであること
- ドキュメント内のデータ数が同じであること
- 登録日時がサーバ時刻と極端に離れていないこと
②③ ドキュメント登録をトリガーに、Function経由でAuthenticationからユーザ削除
Firestore Functionsに関数を登録します。
①のドキュメント追加(onCreate)をトリガーに、Authenticationのユーザ情報を削除する流れです。
とても簡単ですね。
exports.deleteUser = functions
.region('asia-northeast1')
.firestore
.document('deleted_users/{docId}')
.onCreate(async (snap, context) => {
const deleteDocument = snap.data();
const uid = deleteDocument.uid;
await auth.deleteUser(uid);
})
④⑤ Authenticationのユーザ削除をトリガーに、Function経由でユーザ情報削除
②③でAuthenticationのユーザが削除された事をトリガーに、Firestore(DB)に保存されているユーザ情報をFunctionsで全削除します。
こちらは、Firebase側が提供している Delete User Data Extensionsを利用します。
Delete User Data Extensionsを利用することで、Authenticationのユーザが削除されたをトリガーに、UIDに紐づく指定したサブコレクションをキレイに削除可能です。
また、下図のようにUI上で削除対象を登録することができます。
②③のような、Functionsのコードを自前で管理する必要もないので、オススメです!
まとめ
Firebase Authentication、Firestoreのユーザデータ削除方法をまとめてみました。
個人Androidアプリ開発で困った箇所なので、同じ悩みを持たれている方の参考になれば嬉しいです!
※ 内容に誤りやこの構成マズイんじゃない?というご意見あれば、コメントやTwitterでご連絡いただけるととても助かります
Author And Source
この問題について(Firebaseの関連するユーザデータ削除を簡単に実現してみる【Authentication,Firestore,Functions】), 我々は、より多くの情報をここで見つけました https://qiita.com/takashikatt/items/e17401ff301b71e821cd著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .