Xoá dữ liệu bằng Hàm đám mây có thể gọi

Trang này mô tả cách sử dụng một Hàm trên đám mây có thể gọi để xoá dữ liệu. Sau khi triển khai hàm này, bạn có thể gọi trực tiếp từ ứng dụng di động hoặc trang web để xoá các tài liệu và bộ sưu tập theo quy trình đệ quy. Ví dụ: bạn có thể sử dụng giải pháp này để cho phép một số người dùng xoá toàn bộ bộ sưu tập.

Để biết những cách khác để xoá bộ sưu tập, hãy xem phần Xoá dữ liệu.

Giải pháp: Xoá dữ liệu bằng một Hàm trên đám mây có thể gọi

Việc xoá toàn bộ bộ sưu tập khỏi một ứng dụng di động bị hạn chế tài nguyên có thể khó triển khai vì những lý do sau:

  • Không có thao tác nào xoá một bộ sưu tập một cách nguyên tử.
  • Việc xoá một tài liệu sẽ không xoá các tài liệu trong bộ sưu tập phụ của tài liệu đó.
  • Nếu tài liệu của bạn có các bộ sưu tập con động, bạn có thể khó biết dữ liệu nào cần xoá cho một đường dẫn nhất định.
  • Việc xoá một tập hợp gồm hơn 500 tài liệu đòi hỏi nhiều thao tác ghi hàng loạt hoặc hàng trăm thao tác xoá đơn lẻ.
  • Trong nhiều ứng dụng, không thích hợp khi cấp cho người dùng cuối quyền xoá toàn bộ bộ sưu tập.

May mắn thay, bạn có thể viết một Hàm trên đám mây có thể gọi để chạy các thao tác xoá an toàn và hiệu quả cho toàn bộ bộ sưu tập hoặc cây bộ sưu tập. Hàm trên đám mây bên dưới triển khai một hàm có thể gọi, nghĩa là bạn có thể gọi hàm này trực tiếp từ ứng dụng di động hoặc trang web của mình như cách bạn gọi hàm cục bộ.

Để triển khai hàm và thử bản minh hoạ, hãy xem mã mẫu.

Hàm trên đám mây

Hàm trên đám mây bên dưới sẽ xoá một bộ sưu tập và tất cả các bộ sưu tập con của bộ sưu tập đó.

Thay vì triển khai logic xoá đệ quy của riêng mình cho Hàm trên đám mây, bạn có thể tận dụng lệnh firestore:delete trong Giao diện dòng lệnh Firebase (CLI). Bạn có thể nhập bất kỳ hàm nào của CLI Firebase vào ứng dụng Node.js bằng cách sử dụng gói firebase-tools.

Firebase CLI sử dụng API REST Cloud Firestore để tìm tất cả tài liệu trong đường dẫn đã chỉ định và xoá từng tài liệu. Phương thức triển khai này không yêu cầu bạn phải biết về hệ phân cấp dữ liệu cụ thể của ứng dụng, thậm chí còn tìm và xoá các tài liệu "mồ côi" không còn tài liệu mẹ.

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 
    };
  });

Lệnh gọi ứng dụng

Để gọi hàm này, hãy tham chiếu đến hàm từ SDK Firebase và truyền các tham số bắt buộc:

Web
/**
 * 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
Lưu ý: Sản phẩm này không dùng được trên các mục tiêu watchOS và App Clip.
    // Snippet not yet written
    
Objective-C
Lưu ý: Sản phẩm này không dùng được trên các mục tiêu watchOS và 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
                    // ...
                }
            });
}

Bằng cách sử dụng SDK ứng dụng cho các hàm trên đám mây có thể gọi, trạng thái xác thực của người dùng và tham số path sẽ được truyền liền mạch đến hàm từ xa. Khi hàm hoàn tất, ứng dụng sẽ nhận được lệnh gọi lại kèm theo kết quả hoặc trường hợp ngoại lệ. Để tìm hiểu cách gọi một hàm trên đám mây từ Android, Apple hoặc một nền tảng khác, hãy đọc tài liệu.

Các điểm hạn chế

Giải pháp hiển thị ở trên minh hoạ việc xoá các bộ sưu tập khỏi một hàm có thể gọi, nhưng bạn cần lưu ý những hạn chế sau:

  • Tính nhất quán – mã ở trên sẽ xoá từng tài liệu một. Nếu bạn truy vấn trong khi đang diễn ra thao tác xoá, kết quả của bạn có thể phản ánh trạng thái hoàn chỉnh một phần, trong đó chỉ có một số tài liệu được nhắm mục tiêu bị xoá. Cũng không có gì đảm bảo rằng các thao tác xoá sẽ thành công hoặc không thành công một cách đồng nhất, vì vậy, hãy chuẩn bị để xử lý các trường hợp xoá một phần.
  • Hết thời gian chờ – hàm ở trên được định cấu hình để chạy trong tối đa 540 giây trước khi hết thời gian chờ. Mã xoá có thể xoá 4.000 tài liệu mỗi giây trong trường hợp tốt nhất. Nếu cần xoá hơn 2.000.000 tài liệu, bạn nên cân nhắc chạy thao tác này trên máy chủ của riêng mình để không bị hết thời gian chờ. Để biết ví dụ về cách xoá bộ sưu tập khỏi máy chủ của riêng bạn, hãy xem bài viết Xoá bộ sưu tập.
  • Việc xoá một lượng lớn tài liệu có thể khiến trình xem dữ liệu trong Bảng điều khiển Google Cloud tải chậm hoặc trả về lỗi hết thời gian chờ.