Na tej stronie opisano, jak używać wywoływalnej funkcji w Cloud Functions do usuwania danych. Po wdrożeniu tej funkcji możesz wywołać ją bezpośrednio z aplikacji mobilnej lub strony internetowej, aby rekurencyjnie usunąć dokumenty i kolekcje. Możesz na przykład użyć tego rozwiązania, aby zezwolić wybranym użytkownikom na usuwanie całych kolekcji.
Inne sposoby usuwania kolekcji znajdziesz w sekcji Usuwanie danych.
Rozwiązanie: usuwanie danych za pomocą wywoływalnej funkcji w Cloud Functions
Usuwanie całych kolekcji z aplikacji mobilnej o ograniczonej ilości zasobów może być trudne do wdrożenia z tych powodów:
- Nie ma operacji, która umożliwia atomowe usunięcie kolekcji.
- Usunięcie dokumentu nie powoduje usunięcia dokumentów z jego podkolekcji.
- Jeśli dokumenty zawierają dynamiczne podzbiory, trudno może być określić, które dane należy usunąć z danej ścieżki.
- Usuwanie kolekcji zawierającej ponad 500 dokumentów wymaga wykonania wielu operacji zapisu wsadowego lub setek pojedynczych operacji usuwania.
- W wielu aplikacjach nie jest wskazane przyznawanie użytkownikom uprawnień do usuwania całych kolekcji.
Na szczęście możesz napisać wywoływalną funkcję Cloud Functions, aby bezpiecznie i efektywnie usuwać całe kolekcje lub drzewa kolekcji. Poniżej przedstawiona funkcja w Cloud Functions implementuje funkcję wywołującą, co oznacza, że można ją wywołać bezpośrednio z aplikacji mobilnej lub witryny, tak jak w przypadku funkcji lokalnej.
Aby wdrożyć funkcję i wypróbować wersję demonstracyjną, zapoznaj się z przykładowym kodem.
Funkcja w Cloud Functions
Funkcja Cloud Functions poniżej usuwa kolekcję i wszystkie jej elementy potomne.
Zamiast implementować własną rekurencyjną logikę usuwania dla funkcji w Google Cloud, możesz użyć polecenia firestore:delete
w interfejsie wiersza poleceń Firebase (CLI). Za pomocą pakietu firebase-tools
możesz importować do aplikacji Node.js dowolną funkcję z wiersza poleceń Firebase.
Interfejs wiersza poleceń Firebase korzysta z interfejsu API REST Cloud Firestore, aby znaleźć wszystkie dokumenty w określonym katalogu i usunąć je pojedynczo. Ta implementacja nie wymaga znajomości konkretnej hierarchii danych w aplikacji. Pozwala nawet znaleźć i usunąć „osierocone” dokumenty, które nie mają już rodzica.
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 }; });
Wywoływanie klienta
Aby wywołać funkcję, uzyskaj odwołanie do niej z pakietu SDK Firebase i podaj wymagane parametry:
Sieć
/** * 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); }); }
Swift
// Snippet not yet written
Objective-C
// Snippet not yet written
Kotlin+KTX
/** * 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 // ... } }); }
Dzięki użyciu pakietu SDK klienta do wywoływanych funkcji w chmurze stan uwierzytelniania użytkownika i parametr path
są bezproblemowo przekazywane do funkcji zdalnej.
Po zakończeniu działania funkcja wywoła klienta z wynikiem lub wyjątkiem. Aby dowiedzieć się, jak wywołać funkcję w chmurze z poziomu Androida, Apple lub innej platformy, przeczytaj dokumentację.
Ograniczenia
Rozwiązanie pokazane powyżej demonstruje usuwanie kolekcji z funkcji wywoływalnej, ale należy pamiętać o tych ograniczeniach:
- Spójność: kod powyżej usuwa dokumenty po jednym. Jeśli wysyłasz zapytanie, gdy trwa operacja usuwania, wyniki mogą odzwierciedlać stan częściowego ukończenia, w którym usunięte są tylko niektóre docelowe dokumenty. Nie ma też gwarancji, że operacje usuwania zakończą się sukcesem lub niepowodzeniem w taki sam sposób, dlatego przygotuj się na przypadki częściowego usunięcia.
- Limity czasu – funkcja powyżej jest skonfigurowana tak, aby działać maksymalnie 540 sekund przed przekroczeniem limitu czasu. W najlepszym przypadku kod usuwania może usunąć 4000 dokumentów na sekundę. Jeśli chcesz usunąć ponad 2 000 000 dokumentów, rozważ wykonanie tej operacji na własnym serwerze, aby nie przekroczyć limitu czasu. Przykład usuwania kolekcji z własnego serwera znajdziesz w sekcji Usuwanie kolekcji.
- Usunięcie dużej liczby dokumentów może spowodować, że przeglądarka danych w konsoli Google Cloud będzie się wczytywać wolno lub zwróci błąd limitu czasu.