How to delete a user and their Firestore document in a callable cloud function
Asked Answered
R

1

6

I'm creating a cloud function in firebase and need some help,I'm trying to delete a user form firebase and delete his document from firestore in one cloud function.

How can I make a batch job / transaction for both auth and firestore, lets say the user tries to delete his account but for some reason the user.delete() function doesn't work (lets say it's down on firebases side for that moment). The user would get en error message that we couldn't delete his account but when he tries to login again he would also get an error because his document doesn't exist.

I looked at the firebase extension to delete user data but it doesn't delete the user account and it seems to have the same problem.

Do I need to handle such edge case in the app/cloud-functions, is it something firebase should take care of or am I just getting something wrong?

Here is my code, if it would help:

const functions = require("firebase-functions");
const admin = require("firebase-admin");

exports.deleteUser = functions.https.onCall(async (data, context) => {
  try {
    const uid = context.auth.uid;
    const db = admin.firestore();
    const collection = db.collection("users");
    await collection.doc(uid).delete();
    await admin.auth.deleteUser(uid); // what if this line fails?
    return "success";
  } catch (err) {
    console.error(err);
    return "error";
  }
});
Radon answered 9/2, 2020 at 3:44 Comment(0)
C
6

This line isn't doing what you think it's doing:

const user = await admin.auth().currentUser;

user is going to be undefined, because admin.auth() doesn't have a property called currentUser (it's an Auth object). The concept of "current user" doesn't exist on backend SDKs. It's a frontend concept only. What you do have, however, is a string uid which is the UID of the authenticated user that invoked the function.

If you want to use the Firebase Admin SDK to delete the user identified by the uid string, then you just need to call deleteUser(uid):

await admin.auth().deleteUser(uid);

By the way, the Delete User Data extension doesn't have to delete the user, because it works by responding to the user deleting their own account using the client SDK. That should actually be enough to make this work.

Campball answered 9/2, 2020 at 3:54 Comment(3)
oops, thanks for the fix and for explaining how the firebase extension works. in my case i don't want to let the user delete his account if he is and admin of a group, therefor i need to delete his account in a function and not in the app.Radon
Well, if the authenticated user is not invoking the function for themselves, then context.auth.uid will be of no use to you for deleting the account. It will have to come in through a parameter, which you then use to call admin.auth().deleteUser(). You might want to give this whole problem another try, and be sure to think carefully about who is invoking the function, and how you're going to determine which user to delete.Campball
wow, thanks a lot for these points, I'm learning as I'm going... I understand that it is not possible to do what I asked in the question.Radon

© 2022 - 2024 — McMap. All rights reserved.