توضّح الصفحة كيفية استخدام دالة Cloud قابلة للاستدعاء لحذف البيانات. بعد نشر هذه الدالة، يمكنك استدعاؤها مباشرةً من تطبيقك على الأجهزة الجوّالة أو موقعك الإلكتروني لحذف المستندات والمجموعات بشكل متكرر. على سبيل المثال، يمكنك استخدام هذا الحلّ لمنح مستخدمين محدّدين إمكانية حذف مجموعات كاملة.
للاطّلاع على طرق أخرى لحذف المجموعات، يُرجى مراجعة مقالة حذف البيانات.
الحلّ: حذف البيانات باستخدام دالة Cloud Function قابلة للاستدعاء
قد يكون من الصعب تنفيذ حذف مجموعات كاملة من تطبيق جوال محدود الموارد للأسباب التالية:
- لا تتوفّر عملية لحذف مجموعة بشكل كامل.
- لا يؤدي حذف مستند إلى حذف المستندات في مجموعاته الفرعية.
- إذا كانت مستنداتك تحتوي على مجموعات فرعية ديناميكية، قد يكون من الصعب معرفة البيانات التي يجب حذفها لمسار معيّن.
- يتطلب حذف مجموعة تضم أكثر من 500 مستند إجراء عمليات كتابة مجمّعة متعددة أو مئات عمليات الحذف الفردية.
- في العديد من التطبيقات، ليس من المناسب منح المستخدمين النهائيين إذن المستخدم بحذف مجموعات كاملة.
لحسن الحظ، يمكنك كتابة دالة Cloud قابلة للاستدعاء لتنفيذ عمليات حذف آمنة وفعّالة لمجموعات كاملة أو مجموعات فرعية. تنفّذ دالة Cloud Function أدناه دالة قابلة للاستدعاء، ما يعني أنّه يمكن استدعاؤها مباشرةً من تطبيقك المتوافق مع الأجهزة الجوّالة أو موقعك الإلكتروني كما تفعل مع دالة محلية.
لنشر الدالة وتجربة عرض توضيحي، يمكنك الاطّلاع على الرمز النموذجي.
دالة Cloud
تحذف دالة Cloud Function أدناه مجموعة وجميع توابعها.
بدلاً من تنفيذ منطق الحذف المتكرر الخاص بك لدالة Cloud Function،
يمكنك الاستفادة من الأمر firestore:delete في
واجهة سطر الأوامر (CLI) في Firebase. يمكنك استيراد أي دالة من Firebase CLI إلى تطبيق Node.js باستخدام حزمة firebase-tools.
تستخدم واجهة سطر الأوامر في 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 }; });
استدعاء العميل
لاستدعاء الدالة، احصل على مرجع للدالة من حزمة تطوير البرامج (SDK) لمنصّة 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
// 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 بسلاسة إلى الدالة البعيدة.
عند اكتمال الدالة، سيتلقّى العميل ردّ اتصال يتضمّن
النتيجة أو استثناءً. لمعرفة كيفية استدعاء دالة Cloud من Android أو Apple أو نظام أساسي آخر، يُرجى الاطّلاع على المستندات.
القيود
يوضّح الحلّ أعلاه كيفية حذف المجموعات من دالة قابلة للاستدعاء، ولكن يجب الانتباه إلى القيود التالية:
- الاتساق: يحذف الرمز أعلاه المستندات واحدًا تلو الآخر. إذا أجريت طلب بحث أثناء عملية حذف جارية، قد تعكس النتائج حالة مكتملة جزئيًا حيث يتم حذف بعض المستندات المستهدفة فقط. ولا يمكن أيضًا ضمان نجاح عمليات الحذف أو فشلها بشكل موحّد، لذا يجب الاستعداد للتعامل مع حالات الحذف الجزئي.
- المهلات: تم ضبط الدالة أعلاه لتعمل لمدة أقصاها 540 ثانية قبل انتهاء المهلة. يمكن لرمز الحذف حذف 4000 مستند في الثانية في أفضل الأحوال. إذا كنت بحاجة إلى حذف أكثر من 2,000,000 مستند، ننصحك بتشغيل العملية على خادمك الخاص حتى لا تنتهي المهلة. للاطّلاع على مثال على كيفية حذف مجموعة من خادمك، يُرجى مراجعة حذف المجموعات.
- قد يؤدي حذف عدد كبير من المستندات إلى بطء تحميل عارض البيانات في وحدة تحكّم Google Cloud أو ظهور خطأ انتهاء المهلة.