Daten mit einer Callable Cloud Function löschen

Auf der Seite wird beschrieben, wie Sie eine aufrufbare Cloud-Funktion zum Löschen von Daten verwenden. Sobald Sie diese Funktion bereitgestellt haben, können Sie sie direkt von Ihrer mobilen App oder Website aus aufrufen, um Dokumente und Sammlungen rekursiv zu löschen. Mit dieser Lösung können Sie beispielsweise ausgewählten Benutzern die Möglichkeit geben, ganze Sammlungen zu löschen.

Weitere Möglichkeiten zum Löschen von Sammlungen finden Sie unter Daten löschen .

Lösung: Daten mit einer aufrufbaren Cloud-Funktion löschen

Das Löschen ganzer Sammlungen aus einer ressourcenbeschränkten mobilen App kann aus folgenden Gründen schwierig umzusetzen sein:

  • Es gibt keinen Vorgang, der eine Sammlung atomar löscht.
  • Durch das Löschen eines Dokuments werden die Dokumente in seinen Untersammlungen nicht gelöscht.
  • Wenn Ihre Dokumente über dynamische Untersammlungen verfügen, kann es schwierig sein, zu wissen, welche Daten für einen bestimmten Pfad gelöscht werden sollen.
  • Das Löschen einer Sammlung von mehr als 500 Dokumenten erfordert mehrere gestapelte Schreibvorgänge oder Hunderte einzelner Löschvorgänge.
  • In vielen Apps ist es nicht angebracht, Endbenutzern die Berechtigung zum Löschen ganzer Sammlungen zu erteilen.

Glücklicherweise können Sie eine aufrufbare Cloud-Funktion schreiben, um sichere und leistungsstarke Löschvorgänge ganzer Sammlungen oder Sammlungsbäume durchzuführen. Die folgende Cloud-Funktion implementiert eine aufrufbare Funktion , was bedeutet, dass sie wie eine lokale Funktion direkt von Ihrer mobilen App oder Website aufgerufen werden kann.

Informationen zum Bereitstellen der Funktion und zum Testen einer Demo finden Sie im Beispielcode .

Cloud-Funktion

Die folgende Cloud-Funktion löscht eine Sammlung und alle ihre Nachkommen.

Anstatt Ihre eigene rekursive Löschlogik für Ihre Cloud-Funktion zu implementieren, können Sie den Befehl firestore:delete in der Firebase Command Line Interface (CLI) nutzen. Mit dem firebase-tools Paket können Sie jede Funktion der Firebase-CLI in Ihre Node.js-Anwendung importieren.

Die Firebase-CLI verwendet die Cloud Firestore REST API, um alle Dokumente unter dem angegebenen Pfad zu finden und einzeln zu löschen. Diese Implementierung erfordert keine Kenntnis der spezifischen Datenhierarchie Ihrer App und findet und löscht sogar „verwaiste“ Dokumente, die kein übergeordnetes Element mehr haben.

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 
    };
  });

Client-Aufruf

Um die Funktion aufzurufen, rufen Sie einen Verweis auf die Funktion vom Firebase SDK ab und übergeben Sie die erforderlichen Parameter:

Netz
/**
 * 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);
        });
}
Schnell
Hinweis: Dieses Produkt ist nicht auf watchOS- und App Clip-Zielen verfügbar.
    // Snippet not yet written
    
Ziel c
Hinweis: Dieses Produkt ist nicht auf watchOS- und App Clip-Zielen verfügbar.
    // 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
                    // ...
                }
            });
}

Durch die Verwendung des Client-SDK für aufrufbare Cloud-Funktionen werden der Authentifizierungsstatus des Benutzers und der path nahtlos an die Remote-Funktion übergeben. Wenn die Funktion abgeschlossen ist, erhält der Client einen Rückruf mit dem Ergebnis oder einer Ausnahme. Um zu erfahren, wie Sie eine Cloud-Funktion von Android, Apple oder einer anderen Plattform aufrufen, lesen Sie die Dokumentation .

Einschränkungen

Die oben gezeigte Lösung veranschaulicht das Löschen von Sammlungen aus einer aufrufbaren Funktion. Sie sollten sich jedoch der folgenden Einschränkungen bewusst sein:

  • Konsistenz – der obige Code löscht Dokumente einzeln. Wenn Sie während eines laufenden Löschvorgangs eine Abfrage durchführen, spiegeln Ihre Ergebnisse möglicherweise einen teilweise abgeschlossenen Status wider, in dem nur einige Zieldokumente gelöscht werden. Es gibt auch keine Garantie dafür, dass die Löschvorgänge einheitlich erfolgreich sind oder fehlschlagen. Seien Sie daher auf Fälle teilweiser Löschung vorbereitet.
  • Zeitüberschreitungen : Die obige Funktion ist so konfiguriert, dass sie maximal 540 Sekunden lang ausgeführt wird, bevor eine Zeitüberschreitung auftritt. Der Löschcode kann im besten Fall 4000 Dokumente pro Sekunde löschen. Wenn Sie mehr als 2.000.000 Dokumente löschen müssen, sollten Sie erwägen, den Vorgang auf Ihrem eigenen Server auszuführen, damit es nicht zu einer Zeitüberschreitung kommt. Ein Beispiel zum Löschen einer Sammlung von Ihrem eigenen Server finden Sie unter Sammlungen löschen .