На этой странице описано, как использовать вызываемую облачную функцию для удаления данных. После развертывания этой функции вы сможете вызывать её непосредственно из мобильного приложения или веб-сайта для рекурсивного удаления документов и коллекций. Например, это решение можно использовать, чтобы предоставить избранным пользователям возможность удалять целые коллекции.
Другие способы удаления коллекций см. в разделе Удаление данных .
Решение: удалить данные с помощью вызываемой облачной функции
Удаление целых коллекций из мобильного приложения с ограниченными ресурсами может оказаться затруднительным по следующим причинам:
- Операции, которая атомарно удаляет коллекцию, не существует.
- Удаление документа не приводит к удалению документов в его подколлекциях.
- Если в ваших документах есть динамические подколлекции, может быть сложно определить, какие данные следует удалить для определенного пути.
- Удаление коллекции из более чем 500 документов требует нескольких пакетных операций записи или сотен одиночных удалений.
- Во многих приложениях нецелесообразно предоставлять конечным пользователям разрешение на удаление целых коллекций.
К счастью, вы можете написать вызываемую облачную функцию для безопасного и производительного удаления целых коллекций или деревьев коллекций. Представленная ниже облачная функция реализует вызываемую функцию , что означает, что её можно вызывать непосредственно из мобильного приложения или веб-сайта, как локальную функцию.
Чтобы развернуть функцию и опробовать демо, ознакомьтесь с примером кода .
Облачная функция
Функция Cloud, представленная ниже, удаляет коллекцию и всех ее потомков.
Вместо реализации собственной рекурсивной логики удаления для вашей функции Cloud вы можете воспользоваться командой firestore:delete
в интерфейсе командной строки Firebase (CLI). Вы можете импортировать любую функцию Firebase CLI в ваше приложение Node.js с помощью пакета firebase-tools
.
Интерфейс командной строки Firebase использует REST API Cloud Firestore для поиска всех документов по указанному пути и их удаления по отдельности. Эта реализация не требует знания иерархии данных вашего приложения и позволяет даже находить и удалять «потерянные» документы, у которых больше нет родительских элементов.
Node.js
/** * Initiate a recursive delete of documents at a given path. * * The calling user must be authenticated and have the custom "admin" attribute * set to true on the auth token. * * This delete is NOT an atomic operation and it's possible * that it may fail after only deleting some documents. * * @param {string} data.path the document or collection path to delete. */ exports.recursiveDelete = functions .runWith({ timeoutSeconds: 540, memory: '2GB' }) .https.onCall(async (data, context) => { // Only allow admin users to execute this function. if (!(context.auth && context.auth.token && context.auth.token.admin)) { throw new functions.https.HttpsError( 'permission-denied', 'Must be an administrative user to initiate delete.' ); } const path = data.path; console.log( `User ${context.auth.uid} has requested to delete path ${path}` ); // Run a recursive delete on the given document or collection path. // The 'token' must be set in the functions config, and can be generated // at the command line by running 'firebase login:ci'. await firebase_tools.firestore .delete(path, { project: process.env.GCLOUD_PROJECT, recursive: true, force: true, token: functions.config().fb.token }); return { path: path }; });
Вызов клиента
Чтобы вызвать функцию, получите ссылку на функцию из Firebase SDK и передайте необходимые параметры:
Интернет
/** * Call the 'recursiveDelete' callable function with a path to initiate * a server-side delete. */ function deleteAtPath(path) { var deleteFn = firebase.functions().httpsCallable('recursiveDelete'); deleteFn({ path: path }) .then(function(result) { logMessage('Delete success: ' + JSON.stringify(result)); }) .catch(function(err) { logMessage('Delete failed, see console,'); console.warn(err); }); }
Быстрый
// Snippet not yet written
Objective-C
// Snippet not yet written
Kotlin
/** * Call the 'recursiveDelete' callable function with a path to initiate * a server-side delete. */ fun deleteAtPath(path: String) { val deleteFn = Firebase.functions.getHttpsCallable("recursiveDelete") deleteFn.call(hashMapOf("path" to path)) .addOnSuccessListener { // Delete Success // ... } .addOnFailureListener { // Delete Failed // ... } }
Java
/** * Call the 'recursiveDelete' callable function with a path to initiate * a server-side delete. */ public void deleteAtPath(String path) { Map<String, Object> data = new HashMap<>(); data.put("path", path); HttpsCallableReference deleteFn = FirebaseFunctions.getInstance().getHttpsCallable("recursiveDelete"); deleteFn.call(data) .addOnSuccessListener(new OnSuccessListener<HttpsCallableResult>() { @Override public void onSuccess(HttpsCallableResult httpsCallableResult) { // Delete Success // ... } }) .addOnFailureListener(new OnFailureListener() { @Override public void onFailure(@NonNull Exception e) { // Delete failed // ... } }); }
Используя клиентский SDK для вызываемых облачных функций, состояние аутентификации пользователя и параметр path
автоматически передаются в удалённую функцию. После завершения функции клиент получит обратный вызов с результатом или исключением. Чтобы узнать, как вызвать облачную функцию из Android, Apple или другой платформы, ознакомьтесь с документацией .
Ограничения
Приведенное выше решение демонстрирует удаление коллекций из вызываемой функции, но следует учитывать следующие ограничения:
- Согласованность — приведённый выше код удаляет документы по одному. Если вы выполняете запрос во время выполнения операции удаления, результаты могут отражать частично завершённое состояние, когда удалены только некоторые из указанных документов. Также нет гарантии, что операции удаления будут выполнены успешно или неудачно, поэтому будьте готовы к ситуациям частичного удаления.
- Тайм-ауты — указанная выше функция настроена на выполнение максимум 540 секунд до истечения времени ожидания. Код удаления может удалить 4000 документов в секунду в лучшем случае. Если вам нужно удалить более 2 000 000 документов, рекомендуется запустить операцию на вашем собственном сервере, чтобы избежать тайм-аута. Пример удаления коллекции с вашего сервера см. в разделе Удаление коллекций .
- Удаление большого количества документов может привести к медленной загрузке средства просмотра данных в консоли Google Cloud или к возникновению ошибки тайм-аута.