מחק נתונים עם פונקציית ענן הניתנת להתקשרות

הדף מתאר כיצד להשתמש בפונקציית ענן הניתנת להתקשרות כדי למחוק נתונים. לאחר שתפרוס פונקציה זו, תוכל להתקשר אליה ישירות מהאפליקציה לנייד או מהאתר שלך כדי למחוק באופן רקורסיבי מסמכים ואוספים. לדוגמה, אתה יכול להשתמש בפתרון זה כדי לתת למשתמשים נבחרים את היכולת למחוק אוספים שלמים.

לדרכים אחרות למחיקת אוספים, ראה מחיקת נתונים .

פתרון: מחק נתונים עם פונקציית ענן הניתנת להתקשרות

מחיקת אוספים שלמים מאפליקציה ניידת מוגבלת במשאבים עלולה להיות קשה ליישום מהסיבות הבאות:

  • אין שום פעולה שמוחקת אטומית אוסף.
  • מחיקת מסמך אינה מוחקת את המסמכים באוספים המשנה שלו.
  • אם למסמכים שלך יש אוספי משנה דינמיים, יכול להיות קשה לדעת אילו נתונים למחוק עבור נתיב נתון.
  • מחיקת אוסף של יותר מ-500 מסמכים דורשת מספר פעולות כתיבה אצווה או מאות מחיקות בודדות.
  • באפליקציות רבות, אין זה מתאים לתת למשתמשי קצה הרשאה למחוק אוספים שלמים.

למרבה המזל, אתה יכול לכתוב פונקציית ענן הניתנת להתקשרות כדי להפעיל מחיקות בטוחות וביצועיות של אוספים שלמים או עצי אוסף. פונקציית הענן שלהלן מיישמת פונקציה הניתנת להתקשרות , כלומר ניתן להתקשר אליה ישירות מהאפליקציה לנייד או מאתר האינטרנט שלך כפי שהיית עושה עבור פונקציה מקומית.

כדי לפרוס את הפונקציה ולנסות הדגמה, עיין בקוד לדוגמה .

פונקציית ענן

פונקציית הענן למטה מוחקת אוסף ואת כל צאצאיו.

במקום ליישם לוגיקת מחיקה רקורסיבית משלך עבור פונקציית הענן שלך, אתה יכול לנצל את הפקודה 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 
    };
  });

הזמנה ללקוח

כדי לקרוא לפונקציה, קבל הפניה לפונקציה מה-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);
        });
}
מָהִיר
הערה: מוצר זה אינו זמין ביעדי 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 של הלקוח עבור פונקציות ענן הניתנות להתקשרות, מצב האימות של המשתמשים ופרמטר path מועברים בצורה חלקה לפונקציה המרוחקת. בסיום הפונקציה, הלקוח יקבל התקשרות חוזרת עם התוצאה או חריגה. כדי ללמוד כיצד לקרוא לפונקציית ענן מאנדרואיד, אפל או פלטפורמה אחרת, קרא את התיעוד .

מגבלות

הפתרון המוצג לעיל מדגים מחיקת אוספים מפונקציה הניתנת להתקשרות, אך עליך להיות מודע למגבלות הבאות:

  • עקביות - הקוד למעלה מוחק מסמכים אחד בכל פעם. אם תבצע שאילתה בזמן שיש פעולת מחיקה מתמשכת, התוצאות שלך עשויות לשקף מצב שלם בחלקו שבו רק חלק מהמסמכים הממוקדים נמחקים. אין גם ערובה שפעולות המחיקה יצליחו או ייכשלו באופן אחיד, אז היו מוכנים לטפל במקרים של מחיקה חלקית.
  • זמן קצוב - הפונקציה שלמעלה מוגדרת לפעול למשך 540 שניות לכל היותר לפני הפסקת הזמן. קוד המחיקה יכול למחוק 4000 מסמכים בשנייה במקרה הטוב. אם אתה צריך למחוק יותר מ-2,000,000 מסמכים, כדאי לשקול להפעיל את הפעולה בשרת משלך כדי שלא יפסק זמן קצוב. לדוגמא כיצד למחוק אוסף מהשרת שלך, ראה מחיקת אוספים .