حذف داده‌ها با «تابع ابری فراخوانی‌شدنی»

این صفحه نحوه استفاده از Cloud Function قابل‌فراخوانی برای حذف داده‌ها را شرح می‌دهد. وقتی این تابع را مستقر کردید، می‌توانید آن را مستقیماً از برنامه تلفن همراه یا وب‌سایتتان فراخوانی کنید تا اسناد و مجموعه‌ها را به‌صورت بازگشتی حذف کنید. برای مثال، می‌توانید از این راهکار استفاده کنید تا به کاربران منتخب امکان دهید کل مجموعه‌ها را حذف کنند.

برای روش‌های دیگر حذف مجموعه‌ها، به حذف داده‌ها مراجعه کنید.

راه‌حل: حذف داده‌ها با Cloud Function قابل‌فراخوانی

حذف کل مجموعه‌ها از برنامه تلفن همراه با منابع محدود می‌تواند به‌دلایل زیر دشوار باشد:

  • هیچ عملیاتی وجود ندارد که یک مجموعه را به‌صورت اتمی حذف کند.
  • حذف کردن سند باعث حذف شدن اسناد موجود در زیرمجموعه‌های آن نمی‌شود.
  • اگر اسناد شما دارای زیرمجموعه‌های پویا باشند، ممکن است تشخیص اینکه چه داده‌هایی باید برای یک مسیر خاص حذف شوند، دشوار باشد.
  • حذف مجموعه‌ای با بیش‌از ۵۰۰ سند به چندین عملیات نوشتن دسته‌ای یا صدها حذف تکی نیاز دارد.
  • در بسیاری از برنامه‌ها، مناسب نیست که به کاربران نهایی اجازه داده شود کل مجموعه‌ها را حذف کنند.

خوشبختانه، می‌توانید یک تابع Cloud قابل فراخوانی بنویسید تا حذف‌های ایمن و کارآمدی از کل مجموعه‌ها یا درخت‌های مجموعه اجرا کنید. «تابع ابری» زیر یک تابع قابل‌فراخوانی را پیاده‌سازی می‌کند، یعنی می‌توان آن را مستقیماً از برنامه تلفن همراه یا وب‌سایت شما فراخوانی کرد، درست مثل یک تابع محلی.

برای استقرار تابع و امتحان کردن نسخه نمایشی، کد نمونه را ببینید.

تابع ابری

«تابع ابری» زیر یک مجموعه و همه زیرمجموعه‌های آن را حذف می‌کند.

به‌جای پیاده‌سازی منطق حذف بازگشتی خودتان برای Cloud Function، می‌توانید از فرمان firestore:delete در «میانای خط فرمان» (CLI) Firebase استفاده کنید. می‌توانید هر تابعی از واسط خط فرمان Firebase را بااستفاده از بسته firebase-tools به برنامه Node.js خود وارد کنید.

واسط خط فرمان Firebase از Cloud Firestore REST API استفاده می‌کند تا همه اسناد موجود در مسیر مشخص‌شده را پیدا کند و آن‌ها را به‌صورت جداگانه حذف کند. این پیاده‌سازی نیازی به دانستن سلسله‌مراتب داده‌های خاص برنامه شما ندارد و حتی اسناد «یتیم» را که دیگر والد ندارند پیدا و حذف می‌کند.

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 دریافت کنید و پارامترهای لازم را ارسال کنید:

وب
/**
 * 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
توجه: این محصول در watchOS و App Clip دردسترس نیست.
    // Snippet not yet written
    
Objective-C
توجه: این محصول در watchOS و App Clip دردسترس نیست.
    // 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
                    // ...
                }
            });
}

بااستفاده از کیت توسعه نرم‌افزار کارخواه برای توابع ابری قابل‌فراخوانی، وضعیت اصالت‌سنجی کاربر و پارامتر path به‌طور یکپارچه به تابع راه دور منتقل می‌شوند. وقتی تابع تکمیل می‌شود، مشتری یک فراخوانی برگشتی با نتیجه یا استثنا دریافت می‌کند. برای آشنایی با نحوه فراخوانی تابع ابری از Android،‏ Apple، یا پلاتفرم‌های دیگر، اسناد را بخوانید.

محدودیت‌ها

راهکار نشان‌داده‌شده در بالا حذف مجموعه‌ها از تابع فراخوانی‌شدنی را نشان می‌دهد، اما باید از محدودیت‌های زیر آگاه باشید:

  • سازگاری - کد بالا اسناد را یکی‌یکی حذف می‌کند. اگر درحالی‌که عملیات حذف درحال انجام است پُرسمان کنید، ممکن است نتایج شما وضعیت نیمه‌کامل را نشان دهد که در آن فقط برخی‌از اسناد هدف حذف شده‌اند. همچنین هیچ تضمینی وجود ندارد که عملیات حذف به‌طور یکنواخت موفق یا ناموفق باشد، بنابراین برای رسیدگی به موارد حذف جزئی آماده باشید.
  • زمان‌تمام - تابع بالا به‌گونه‌ای پیکربندی شده است که حداکثر ۵۴۰ ثانیه قبل‌از زمان‌تمام اجرا شود. کد حذف می‌تواند در بهترین حالت ۴۰۰۰ سند در ثانیه را حذف کند. اگر لازم است بیش‌از ۲٬۰۰۰٬۰۰۰ سند را حذف کنید، باید این عملیات را در سرور خودتان اجرا کنید تا مهلت آن تمام نشود. برای مشاهده نمونه‌ای از نحوه حذف کردن مجموعه از سرور خودتان، حذف کردن مجموعه‌ها را ببینید.
  • حذف تعداد زیادی سند ممکن است باعث شود نمایشگر داده در کنسول Google Cloud به‌کندی بار شود یا خطای اتمام مهلت برگرداند.