mirror of
https://github.com/AmruthPillai/Reactive-Resume.git
synced 2025-11-13 16:22:59 +10:00
Updated "deleteUser" Firebase cloud function implementation, UI call and error handling
This commit is contained in:
@ -10,41 +10,49 @@ function timeout(ms) {
|
|||||||
return new Promise((resolve) => setTimeout(resolve, ms));
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||||
}
|
}
|
||||||
|
|
||||||
async function asyncForEach(array, callback) {
|
const deleteUserFunctionHandler = async (_, { auth }) => {
|
||||||
for (let index = 0; index < array.length; index++) {
|
if (!auth) {
|
||||||
// eslint-disable-next-line no-await-in-loop
|
throw new functions.https.HttpsError(
|
||||||
await callback(array[index], index, array);
|
'failed-precondition',
|
||||||
|
'The function must be called while authenticated.',
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
try {
|
||||||
|
// 1. Delete user resumes
|
||||||
|
const userId = auth.uid;
|
||||||
|
const userResumesDataSnapshot = await admin
|
||||||
|
.database()
|
||||||
|
.ref('resumes')
|
||||||
|
.orderByChild('user')
|
||||||
|
.equalTo(userId)
|
||||||
|
.once('value');
|
||||||
|
const userResumes = userResumesDataSnapshot.val();
|
||||||
|
if (userResumes) {
|
||||||
|
Object.keys(userResumes).forEach(async (resumeId) => {
|
||||||
|
await admin.database().ref(`resumes/${resumeId}`).remove();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Delete user
|
||||||
|
const userDataSnapshot = await admin
|
||||||
|
.database()
|
||||||
|
.ref(`users/${userId}`)
|
||||||
|
.once('value');
|
||||||
|
const user = userDataSnapshot.val();
|
||||||
|
if (user) {
|
||||||
|
await admin.database().ref(`users/${userId}`).remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} catch (error) {
|
||||||
|
throw new functions.https.HttpsError('internal', error.message);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
exports.deleteUser = functions
|
exports.deleteUser = functions
|
||||||
.runWith({ memory: '256MB' })
|
.runWith({ memory: '256MB' })
|
||||||
.https.onCall((_, { auth }) => {
|
.https.onCall(deleteUserFunctionHandler);
|
||||||
if (!auth) {
|
|
||||||
throw new functions.https.HttpsError(
|
|
||||||
'failed-precondition',
|
|
||||||
'The function must be called while authenticated.',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Promise((resolve) => {
|
|
||||||
const resumesRef = admin.database().ref('resumes');
|
|
||||||
|
|
||||||
resumesRef.once('value', async (snapshot) => {
|
|
||||||
const data = snapshot.val();
|
|
||||||
|
|
||||||
const resumes = Object.keys(data).filter(
|
|
||||||
(x) => data[x].user === auth.uid,
|
|
||||||
);
|
|
||||||
|
|
||||||
await asyncForEach(resumes, async (id) => {
|
|
||||||
await admin.database().ref(`resumes/${id}`).remove();
|
|
||||||
});
|
|
||||||
|
|
||||||
resolve();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
exports.printResume = functions
|
exports.printResume = functions
|
||||||
.runWith({ memory: '1GB' })
|
.runWith({ memory: '1GB' })
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import React, { memo, useContext, useState } from 'react';
|
import React, { memo, useContext, useState } from 'react';
|
||||||
import { FaAngleDown } from 'react-icons/fa';
|
import { FaAngleDown } from 'react-icons/fa';
|
||||||
import { useTranslation, Trans } from 'react-i18next';
|
import { useTranslation, Trans } from 'react-i18next';
|
||||||
|
import { toast } from 'react-toastify';
|
||||||
import UserContext from '../../../../contexts/UserContext';
|
import UserContext from '../../../../contexts/UserContext';
|
||||||
import Button from '../../../shared/Button';
|
import Button from '../../../shared/Button';
|
||||||
import Heading from '../../../shared/Heading';
|
import Heading from '../../../shared/Heading';
|
||||||
@ -40,10 +41,20 @@ const Settings = ({ id }) => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
setDeleteText('Buh bye! :(');
|
setDeleteText(t('shared.buttons.loading'));
|
||||||
setTimeout(() => {
|
|
||||||
deleteAccount();
|
setTimeout(
|
||||||
}, 500);
|
() =>
|
||||||
|
deleteAccount()
|
||||||
|
.then(() => {
|
||||||
|
setDeleteText('Buh bye! :(');
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
toast.error(error.message);
|
||||||
|
setDeleteText(t('builder.settings.dangerZone.button'));
|
||||||
|
}),
|
||||||
|
500,
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@ -76,13 +76,13 @@ const UserProvider = ({ children }) => {
|
|||||||
const deleteAccount = async () => {
|
const deleteAccount = async () => {
|
||||||
const { currentUser } = firebase.auth();
|
const { currentUser } = firebase.auth();
|
||||||
const deleteUser = firebase.functions().httpsCallable('deleteUser');
|
const deleteUser = firebase.functions().httpsCallable('deleteUser');
|
||||||
deleteUser();
|
|
||||||
|
await deleteUser();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
deleteUser();
|
|
||||||
await currentUser.delete();
|
await currentUser.delete();
|
||||||
} catch (e) {
|
} catch (error) {
|
||||||
if (e.code === 'auth/requires-recent-login') {
|
if (error.code === 'auth/requires-recent-login') {
|
||||||
await loginWithGoogle();
|
await loginWithGoogle();
|
||||||
await currentUser.delete();
|
await currentUser.delete();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user