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