Below is my firebase function:
const admin = require('firebase-admin');
const firebase_tools = require('firebase-tools');
const functions = require('firebase-functions');
admin.initializeApp();
exports.deleteUser = functions
.runWith({
timeoutSeconds: 540,
memory: '2GB'
})
.https.onCall((data, context) => {
const userId = context.auth.uid;
var promises = [];
// DELETE DATA
var paths = ['users/' + userId, 'messages/' + userId, 'chat/' + userId, 'like/' + userId];
paths.forEach((path) => {
promises.push(
recursiveDelete(path).then( () => {
return 'success';
}
).catch( (error) => {
console.log('Error deleting user data: ', error);
})
);
});
// DELETE FILES
const bucket = admin.storage().bucket();
var image_paths = ["avatar/" + userId, "avatar2/" + userId, "avatar3/" + userId];
image_paths.forEach((path) => {
promises.push(
bucket.file(path).delete().then( () => {
return 'success';
}
).catch( (error) => {
console.log('Error deleting user data: ', error);
})
);
});
// DELETE USER
promises.push(
admin.auth().deleteUser(userId)
.then( () => {
console.log('Successfully deleted user');
return true;
})
.catch((error) => {
console.log('Error deleting user:', error);
})
);
return Promise.all(promises).then(() => {
return true;
}).catch(er => {
console.error('...', er);
});
});
function recursiveDelete(path, context) {
return firebase_tools.firestore
.delete(path, {
project: process.env.GCLOUD_PROJECT,
recursive: true,
yes: true,
token: functions.config().fb.token
})
.then(() => {
return {
path: path
}
}).catch( (error) => {
console.log('error: ', error);
return error;
});
}
// [END recursive_delete_function]
When calling this function, how can I pass in the context.auth.id?
Below is what i've tried:
async function deleteAccount(userId) {
const deleteUser = firebase.functions().httpsCallable("deleteUser");
deleteUser({ userId }).then((result) => {
console.log(result.data);
});
}
But im getting the following error:
Unhandled error TypeError: Cannot read property 'uid' of undefined
I know the the context.auth.id is available server side but In this instance I need a way i can pass it in.
You don't have to pass user's UID in callable cloud function. The user must be logged in with Firebase authentication and Firebase SDKs will take care of the rest.
Can you try logging current user in deleteAccount function before calling cloud function just to ensure user is logged in? Also context.auth.uid is UID of user that is calling the function. If you want to access the userId that you are passing in the function, refactor the code as shown below.
The deleteUser() function would take only 1 parameter that's the data you want to pass in Cloud functions.
// not deleteUser({}, { userId })
deleteUser({ userId }).then((result) => {
console.log(result.data);
});
When you are explicitly passing any data in Cloud function, that can be access from data and not context:
const { userId } = data;