Menghapus Koleksi dan Subkoleksi

Menghapus data di Cloud Firestore, terutama dari aplikasi seluler dengan resource terbatas, dapat sulit diterapkan dengan benar karena alasan berikut:

  • Tidak ada operasi yang menghapus koleksi secara menyeluruh.
  • Menghapus dokumen tidak menghapus dokumen dalam subkoleksinya.
  • Jika dokumen Anda memiliki subkoleksi dinamis, mungkin sulit untuk mengetahui data apa yang harus dihapus untuk sebuah lokasi tertentu.
  • Menghapus koleksi lebih dari 500 dokumen memerlukan beberapa operasi tulis bertumpuk atau ratusan penghapusan tunggal.
  • Di banyak aplikasi, memberikan izin kepada pengguna akhir untuk menghapus seluruh koleksi bukanlah tindakan yang tepat.

Walau begitu, Anda dapat menulis Cloud Function untuk menjalankan penghapusan yang aman dan tepat untuk seluruh koleksi atau pohon koleksi.

Sebelum melanjutkan, baca tentang model data Cloud Firestore.

Solusi: Hapus data dengan Cloud Function yang Dapat Dipanggil

Panduan ini menjelaskan cara menggunakan Cloud Function yang dapat dipanggil untuk menghapus data. Setelah menerapkan fungsi ini, Anda dapat memanggilnya langsung dari aplikasi seluler atau situs Anda untuk menghapus dokumen dan koleksi secara berulang.

Untuk menerapkan fungsi tersebut dan mencoba demo, lihat kode contoh.

Cloud Function

Cloud Function di bawah ini akan menghapus koleksi dan semua turunannya.

Anda dapat memanfaatkan perintah firestore:delete di Firebase Command Line Interface (CLI), dan tidak perlu menerapkan logika penghapusan berulang untuk Cloud Function. Anda dapat mengimpor fungsi apa pun dari Firebase CLI ke aplikasi Node.js sendiri menggunakan paket firebase-tools.

Firebase CLI menggunakan REST API Cloud Firestore untuk menemukan semua dokumen pada lokasi yang ditentukan dan menghapusnya satu per satu. Penerapan ini tidak memerlukan pengetahuan hierarki data tertentu dari aplikasi Anda, dan bahkan akan menemukan serta menghapus dokumen "lama" yang tidak lagi memiliki induk.

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((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'.
    return firebase_tools.firestore
      .delete(path, {
        project: process.env.GCLOUD_PROJECT,
        recursive: true,
        yes: true,
        token: functions.config().fb.token
      })
      .then(() => {
        return {
          path: path
        };
      });
  });

Cloud Function di atas diterapkan sebagai fungsi yang dapat dipanggil, sehingga dapat dipanggil langsung dari aplikasi seluler atau situs Anda, seperti yang Anda lakukan untuk fungsi lokal.

Pemanggilan Klien

Untuk memanggil fungsi ini, dapatkan referensi ke fungsi dari Firebase SDK dan teruskan parameter yang diperlukan:

Web

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

Dengan menggunakan SDK klien untuk fungsi cloud yang dapat dipanggil, status autentikasi pengguna dan parameter path dilewatkan dengan lancar ke fungsi jarak jauh. Ketika fungsi tersebut selesai, klien akan menerima callback dengan hasil atau pengecualian. Untuk mempelajari cara memanggil fungsi cloud dari Android, iOS, atau platform lain, baca dokumentasi.

Pembatasan

Solusi yang ditunjukkan di atas menunjukkan penghapusan koleksi dari fungsi yang dapat dipanggil, tetapi Anda harus mengetahui batasan berikut:

  • Konsistensi - kode di atas menghapus dokumen satu per satu. Jika Anda mengajukan kueri saat berlangsung operasi penghapusan, hasil Anda mungkin akan menggambarkan status yang selesai sebagian, dengan hanya beberapa dokumen yang ditargetkan yang dihapus. Selain itu, tidak ada jaminan bahwa operasi penghapusan akan berhasil atau gagal secara seragam. Jadi, bersiaplah untuk menangani kasus penghapusan sebagian.
  • Waktu tunggu - fungsi di atas dikonfigurasi untuk dijalankan selama maksimal 540 detik sebelum waktu habis. Kode penghapusan dapat menghapus 4.000 dokumen per detik dalam kondisi terbaik. Jika Anda perlu menghapus lebih dari 2 juta dokumen, pertimbangkan untuk menjalankan operasi tersebut pada server Anda sendiri agar tidak mengalami waktu habis.

Kirim masukan tentang...

Butuh bantuan? Kunjungi halaman dukungan kami.