Home > Software design >  firestore cloud functions - delete document
firestore cloud functions - delete document

Time:02-03

i need to deleete an user from firebase auth, and then delete the document corresponding to the user.

The deletion from authentication works, but i dont know how to delete from firestore. I have this

import * as functions from "firebase-functions";
import * as admin from "firebase-admin";

admin.initializeApp();

export const deleteUser = functions.https.onRequest(async (request, response) =>{
    const userEmail = request.body.userEmail;
    const collection = request.body.collection;
    let uid = '';

admin.auth().getUserByEmail(userEmail)
    .then(userRecord => {
        uid = userRecord.uid
        admin.auth().deleteUser(uid)

    })
    .then( () => {
        admin.firestore().collection(collection).doc(uid).get()
        .then(queryResult => {
            queryResult.ref.delete()
        })
        response.status(200).send('deleted')
    })
    .catch(error => {
        response.status(500).send('Failed')
    })
            
})

To try i used postman with

{
    "userEmail": "[email protected]",
    "collection" : "Users"
}

CodePudding user response:

All you have to do is get the doc ref and call the delete function. I leave error handling up to you.

try {
  const userRecord = await admin.auth().getUserByEmail(userEmail)
  await admin.auth().deleteUser(uid)
  await admin.firestore().collection(collection).doc(uid).delete()
  
  return response.status(200).send('deleted');
}
catch{
  return response.status(500).send('Failed')
}

Read the docs: https://firebase.google.com/docs/firestore/manage-data/delete-data#web-version-8

CodePudding user response:

In addition to what @kingkong.js mentioned in their answer (to use DocumentReference#delete()), you also need to ensure your Promise chains are wired up correctly. If not, your function will be terminated before it makes any changes.

import * as functions from "firebase-functions";
import * as admin from "firebase-admin";

admin.initializeApp();

async function deleteUserByEmail(userEmail, collection) {
    // grabs services first to make sure they are initialized
    const auth = admin.auth();
    const db = admin.firestore();
    
    // gets a user by their email, throws an error if not found
    const { uid } = await auth.getUserByEmail(userEmail);
    
    // These can be done in parallel using Promise.all()
    await auth.deleteUser(uid);
    await db.collection(collection)
        .doc(uid)
        .delete();

    return uid;
}

export const deleteUser = functions.https.onRequest(async (request, response) => {
    // TODO: Make sure body (it may be null!), userEmail and
    // collection have values. Return HTTP 400 if not.
    const userEmail = request.body.userEmail;
    const collection = request.body.collection;
    
    // IMPORTANT TODO: Make sure the calling user/admin is properly
    // authorized to delete this account. Return HTTP 403 if not.

    deleteUserByEmail(userEmail, collection)
        .then((uid) => {
            // consider the RESTful empty HTTP 204 response
            response.status(200).send('deleted');
        })
        .catch((err) => {
            if (err && err.code === "auth/user-not-found") {
                // an already deleted user should be considered a success?
                response.status(200).send('deleted');
                return;
            }

            // IMPORTANT: Don't forget to log the error for debugging later
            console.error("Failed to delete user by email. Error Code: "   (err.code || "unknown"), err);
            response.status(500).send('failed')
        }); 
})

You may want to consider using a Callable Cloud Function (functions.https.onCall) instead as it can handle managing the request body, response and authentication for you.

  • Related