ลบข้อมูลด้วย Cloud Function ที่เรียกใช้ได้

หน้านี้จะอธิบายวิธีใช้ Cloud Function ที่เรียกใช้ได้เพื่อลบข้อมูล เมื่อติดตั้งใช้งานฟังก์ชันนี้แล้ว คุณสามารถเรียกใช้ฟังก์ชันดังกล่าวจากแอปบนอุปกรณ์เคลื่อนที่หรือเว็บไซต์โดยตรงเพื่อลบเอกสารและคอลเล็กชันแบบซ้ำ เช่น คุณสามารถใช้โซลูชันนี้เพื่อให้ผู้ใช้บางรายลบคอลเล็กชันทั้งคอลเล็กชันได้

โปรดดูวิธีอื่นๆ ในการลบคอลเล็กชันที่หัวข้อลบข้อมูล

วิธีแก้ไข: ลบข้อมูลด้วย Cloud Function ที่เรียกใช้ได้

การลบคอลเล็กชันทั้งหมดออกจากแอปบนอุปกรณ์เคลื่อนที่ซึ่งมีทรัพยากรจำกัดอาจใช้งานได้ยากเนื่องจากเหตุผลดังต่อไปนี้

  • ไม่มีการดำเนินการที่ลบคอลเล็กชันอย่างสมบูรณ์
  • การลบเอกสารไม่ได้เป็นการลบเอกสารในคอลเล็กชันย่อยของเอกสารนั้น
  • หากเอกสารมีคอลเล็กชันย่อยแบบไดนามิก การจะดูข้อมูลใดในเส้นทางหนึ่งๆ อาจเป็นเรื่องยาก
  • การลบคอลเล็กชันเอกสารมากกว่า 500 รายการต้องใช้การดำเนินการเขียนแบบเป็นกลุ่มหลายรายการหรือการลบรายการเดียวหลายร้อยรายการ
  • ในหลายแอป การให้สิทธิ์ผู้ใช้ปลายทางลบคอลเล็กชันทั้งหมดนั้นไม่เหมาะสม

แต่คุณเขียน Cloud Function ที่เรียกใช้ได้เพื่อดำเนินการลบทั้งคอลเล็กชันหรือทั้งลําดับชั้นคอลเล็กชันได้อย่างปลอดภัยและมีประสิทธิภาพ Cloud Function ด้านล่างใช้ฟังก์ชันที่เรียกใช้ได้ ซึ่งหมายความว่าสามารถเรียกใช้จากแอปบนอุปกรณ์เคลื่อนที่หรือเว็บไซต์ได้โดยตรงเช่นเดียวกับฟังก์ชันในเครื่อง

หากต้องการทําให้ฟังก์ชันใช้งานได้และลองใช้เดโม โปรดดูโค้ดตัวอย่าง

Cloud Function

ฟังก์ชัน Cloud ด้านล่างจะลบคอลเล็กชันและรายการที่สืบทอดทั้งหมด

คุณใช้ประโยชน์จากคำสั่ง firestore:delete ในอินเทอร์เฟซบรรทัดคำสั่ง (CLI) ของ Firebase ได้แทนการใช้ตรรกะการลบแบบซ้ำซ้อนของคุณเองสำหรับ Cloud Function คุณนำเข้าฟังก์ชันใดก็ได้ของ 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
หมายเหตุ: ผลิตภัณฑ์นี้ไม่พร้อมใช้งานบนเป้าหมาย watchOS และ App Clip
    // Snippet not yet written
    
Objective-C
หมายเหตุ: ผลิตภัณฑ์นี้ใช้ไม่ได้กับเป้าหมาย WatchOS และ App Clip
    // 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 ของไคลเอ็นต์สำหรับฟังก์ชัน Cloud ที่เรียกใช้ได้ ระบบจะส่งสถานะการตรวจสอบสิทธิ์ของผู้ใช้และพารามิเตอร์ path ไปยังฟังก์ชันระยะไกลอย่างราบรื่น เมื่อฟังก์ชันเสร็จสมบูรณ์ ไคลเอ็นต์จะได้รับการติดต่อกลับพร้อมผลลัพธ์หรือข้อยกเว้น หากต้องการดูข้อมูลเกี่ยวกับวิธีเรียกใช้ฟังก์ชันระบบคลาวด์จาก Android, Apple หรือแพลตฟอร์มอื่นๆ โปรดอ่านเอกสารประกอบ

ข้อจำกัด

โซลูชันที่แสดงด้านบนแสดงการลบคอลเล็กชันจากฟังก์ชันที่เรียกใช้ได้ แต่คุณควรทราบข้อจํากัดต่อไปนี้

  • ความสอดคล้อง - โค้ดด้านบนจะลบเอกสารทีละรายการ หากคุณค้นหาขณะดำเนินการลบที่ดำเนินอยู่ ผลการค้นหาอาจแสดงสถานะที่สมบูรณ์บางส่วน ซึ่งมีการลบเอกสารเป้าหมายบางรายการเท่านั้น นอกจากนี้ เรายังไม่รับประกันว่าการดำเนินการลบจะสำเร็จหรือล้มเหลวอย่างสม่ำเสมอ ดังนั้นโปรดเตรียมพร้อมรับมือกับกรณีที่มีการลบเพียงบางส่วน
  • การหมดเวลา - ฟังก์ชันด้านบนได้รับการกําหนดค่าให้ทํางานสูงสุด 540 วินาทีก่อนที่จะหมดเวลา รหัสการลบสามารถลบเอกสารได้ 4,000 รายการต่อวินาทีในกรณีที่ดีที่สุด หากต้องการลบเอกสารมากกว่า 2,000,000 รายการ คุณควรพิจารณาเรียกใช้การดำเนินการในเซิร์ฟเวอร์ของคุณเองเพื่อไม่ให้หมดเวลา ดูตัวอย่างวิธีลบคอลเล็กชันจากเซิร์ฟเวอร์ของคุณเองได้ที่ลบคอลเล็กชัน
  • การลบเอกสารจํานวนมากอาจทําให้เครื่องมือดูข้อมูลในคอนโซล Google Cloud โหลดช้าหรือแสดงข้อผิดพลาดเกี่ยวกับเวลาหมด