หน้านี้อธิบายวิธีใช้ Cloud Function ที่สามารถเรียกได้เพื่อลบข้อมูล เมื่อคุณปรับใช้ฟังก์ชันนี้แล้ว คุณสามารถเรียกใช้ได้โดยตรงจากแอปมือถือหรือเว็บไซต์ของคุณเพื่อลบเอกสารและคอลเลกชันแบบวนซ้ำ ตัวอย่างเช่น คุณสามารถใช้โซลูชันนี้เพื่อให้ผู้ใช้สามารถลบคอลเลกชันทั้งหมดได้
สำหรับวิธีอื่นในการลบคอลเลกชัน โปรดดู ลบข้อมูล
วิธีแก้ไข: ลบข้อมูลด้วย Cloud Function ที่สามารถเรียกได้
การลบคอลเลกชันทั้งหมดออกจากแอปมือถือที่มีทรัพยากรจำกัดอาจทำได้ยากด้วยเหตุผลต่อไปนี้:
- ไม่มีการดำเนินการใดที่จะลบคอลเลกชันแบบอะตอมมิก
- การลบเอกสารจะไม่ลบเอกสารในคอลเลกชันย่อย
- หากเอกสารของคุณมีคอลเลกชันย่อยแบบไดนามิก อาจเป็นเรื่องยากที่จะทราบว่าข้อมูลใดที่ควรลบสำหรับเส้นทางที่กำหนด
- การลบคอลเลกชันเอกสารมากกว่า 500 รายการจำเป็นต้องมีการดำเนินการเขียนหลายชุดหรือลบเพียงครั้งเดียวหลายร้อยครั้ง
- ในแอปจำนวนมาก การให้สิทธิ์แก่ผู้ใช้ปลายทางในการลบคอลเลกชันทั้งหมดนั้นไม่เหมาะสม
โชคดีที่คุณสามารถเขียน Cloud Function ที่สามารถเรียกได้ เพื่อให้ดำเนินการลบคอลเลกชันหรือแผนผังคอลเลกชันทั้งหมดได้อย่างปลอดภัยและมีประสิทธิภาพ ฟังก์ชันคลาวด์ด้านล่างใช้ ฟังก์ชันที่เรียกได้ ซึ่งหมายความว่าสามารถเรียกได้โดยตรงจากแอปบนอุปกรณ์เคลื่อนที่หรือเว็บไซต์ของคุณ เช่นเดียวกับที่คุณทำสำหรับฟังก์ชันในเครื่อง
หากต้องการปรับใช้ฟังก์ชันและลองสาธิต โปรดดู โค้ดตัวอย่าง
ฟังก์ชั่นคลาวด์
ฟังก์ชันคลาวด์ด้านล่างจะลบคอลเลกชันและรายการสืบทอดทั้งหมด
แทนที่จะใช้ตรรกะการลบแบบเรียกซ้ำของคุณเองสำหรับฟังก์ชันคลาวด์ คุณสามารถใช้ประโยชน์จากคำสั่ง firestore:delete
ใน Firebase Command Line Interface (CLI) คุณสามารถนำเข้าฟังก์ชันใดๆ ของ Firebase CLI ไปยังแอปพลิเคชัน Node.js ของคุณได้โดยใช้แพ็คเกจ firebase-tools
Firebase CLI ใช้ Cloud Firestore REST API เพื่อค้นหาเอกสารทั้งหมดภายใต้เส้นทางที่ระบุและลบทีละรายการ การใช้งานนี้ไม่จำเป็นต้องมีความรู้เกี่ยวกับลำดับชั้นข้อมูลเฉพาะของแอปของคุณ และยังจะค้นหาและลบเอกสาร "ที่ไม่มีผู้ดูแล" ที่ไม่มีพาเรนต์อีกต่อไป
โหนด 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 SDK และส่งพารามิเตอร์ที่จำเป็น:
เว็บ
/** * 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); }); }
สวิฟท์
// Snippet not yet written
วัตถุประสงค์-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 // ... } }); }
การใช้ SDK ไคลเอ็นต์สำหรับฟังก์ชันคลาวด์ที่เรียกใช้ได้ สถานะการรับรองความถูกต้องของผู้ใช้และพารามิเตอร์ path
จะถูกส่งผ่านไปยังฟังก์ชันระยะไกลได้อย่างราบรื่น เมื่อฟังก์ชันเสร็จสมบูรณ์ ไคลเอ็นต์จะได้รับการติดต่อกลับพร้อมผลลัพธ์หรือข้อยกเว้น หากต้องการเรียนรู้เกี่ยวกับวิธีการเรียกใช้ฟังก์ชันคลาวด์จาก Android, Apple หรือแพลตฟอร์มอื่น โปรดอ่าน เอกสารประกอบ
ข้อจำกัด
วิธีแก้ปัญหาที่แสดงข้างต้นสาธิตการลบคอลเลกชันออกจากฟังก์ชันที่เรียกได้ แต่คุณควรตระหนักถึงข้อจำกัดต่อไปนี้:
- ความสอดคล้อง - โค้ดด้านบนจะลบเอกสารทีละรายการ หากคุณสอบถามในขณะที่ดำเนินการลบอย่างต่อเนื่อง ผลลัพธ์ของคุณอาจสะท้อนถึงสถานะที่สมบูรณ์บางส่วน โดยมีเพียงเอกสารเป้าหมายบางส่วนเท่านั้นที่ถูกลบ ไม่มีการรับประกันว่าการดำเนินการลบจะสำเร็จหรือล้มเหลวอย่างสม่ำเสมอ ดังนั้นให้เตรียมพร้อมรับมือกับกรณีการลบบางส่วน
- หมดเวลา - ฟังก์ชันด้านบนได้รับการกำหนดค่าให้ทำงานสูงสุด 540 วินาทีก่อนหมดเวลา รหัสการลบสามารถลบเอกสารได้ 4,000 ฉบับต่อวินาทีในกรณีที่ดีที่สุด หากคุณต้องการลบเอกสารมากกว่า 2,000,000 รายการ คุณควรพิจารณาเรียกใช้การดำเนินการบนเซิร์ฟเวอร์ของคุณเองเพื่อไม่ให้หมดเวลา สำหรับตัวอย่างวิธีการลบคอลเลกชันออกจากเซิร์ฟเวอร์ของคุณเอง โปรดดูที่ ลบคอลเลกชัน