代码之家  ›  专栏  ›  技术社区  ›  jonasxd360

使用firebase函数删除firestore集合

  •  2
  • jonasxd360  · 技术社区  · 6 年前

    我试图设置一个firebase函数,在删除文档时删除文档的所有子集合。 通过阅读文档,我得出了以下代码:

    // The Cloud Functions for Firebase SDK to create Cloud Functions and setup triggers.
    const functions = require('firebase-functions');
    
    
    
    // // Create and Deploy Your First Cloud Functions
    // // https://firebase.google.com/docs/functions/write-firebase-functions
    //
    // exports.helloWorld = functions.https.onRequest((request, response) => {
    //  response.send("Hello from Firebase!");
    // });
    
    exports.DeleteColletionFunction = functions.firestore
        .document('exampleCollection/{exampleID}')
        .onDelete((snap, context) => {
            // Get an object representing the document prior to deletion
          // e.g. {'name': 'Marie', 'age': 66}
          const deletedValue = snap.data();
          deleteCollection()
    
    
        });
    
    
    
    function deleteCollection(db, collectionPath, batchSize) {
        var collectionRef = db.collection(collectionPath);
        var query = collectionRef.orderBy('__name__').limit(batchSize);
    
        return new Promise((resolve, reject) => {
          deleteQueryBatch(db, query, batchSize, resolve, reject);
        });
      }
    
      function deleteQueryBatch(db, query, batchSize, resolve, reject) {
        query.get()
            .then((snapshot) => {
              // When there are no documents left, we are done
              if (snapshot.size == 0) {
                return 0;
              }
    
              // Delete documents in a batch
              var batch = db.batch();
              snapshot.docs.forEach((doc) => {
                batch.delete(doc.ref);
              });
    
              return batch.commit().then(() => {
                return snapshot.size;
              });
            }).then((numDeleted) => {
              if (numDeleted === 0) {
                resolve();
                return;
              }
    
              // Recurse on the next process tick, to avoid
              // exploding the stack.
              process.nextTick(() => {
                deleteQueryBatch(db, query, batchSize, resolve, reject);
              });
            })
            .catch(reject);
      }
    

    我以前从未使用过云功能,因此不确定下一步该做什么。我看到为了使用delete collection函数,必须传递一个数据库、collectionpath和batchsize。在这种情况下,要传递的正确值是什么?

    我应该使用这行代码来获取firestore数据库吗?

    const database = admin.firestore();
    

    从文档中复制此函数时,我也会遇到一些错误:

    应为“==”,而不是看到“==”

    [埃斯林特]避免背弃承诺。(承诺/不筑巢) (参数)快照:任意

    [eslint]每个then()都应该返回一个值或throw(promise/always return) (参数)resolve:any

    下面是一个屏幕截图,可以看到错误的位置: enter image description here

    谢谢你的帮助!

    更新:
    我改变了一些事情(加上一个承诺):

    // The Cloud Functions for Firebase SDK to create Cloud Functions and setup triggers.
    const functions = require('firebase-functions');
    
    const admin = require('firebase-admin');
    admin.initializeApp(functions.config().firebase);
    
    
    // // Create and Deploy Your First Cloud Functions
    // // https://firebase.google.com/docs/functions/write-firebase-functions
    //
    // exports.helloWorld = functions.https.onRequest((request, response) => {
    //  response.send("Hello from Firebase!");
    // });
    
    exports.DeleteColletionFunction = functions.firestore
        .document('exampleCollection/{exampleID}')
        .onDelete((snap, context) => {
            // Get an object representing the document prior to deletion
          // e.g. {'name': 'Marie', 'age': 66}
          const deletedValue = snap.data();
          const exampleID = context.params.exampleID;
    
          const BATCH_SIZE = 500;
    
          const database = admin.firestore();
    
          const commentsRef = database.collection('exampleCollection').doc(exampleID).collection("comments");
    
          commentsRef.doc('main').delete();
    
          const exampleRef = database.collection('exampleCollection').doc(exampleID).collection("exampleSubCollection");
          const deleteExamples = deleteCollection(database, exampleRef, BATCH_SIZE)
          return Promise.all([deleteExamples]);
    
       });
    
    
    
    /**
     * Delete a collection, in batches of batchSize. Note that this does
     * not recursively delete subcollections of documents in the collection
     */
    function deleteCollection (db, collectionRef, batchSize) {
        var query = collectionRef.orderBy('__name__').limit(batchSize)
    
        return new Promise(function (resolve, reject) {
          deleteQueryBatch(db, query, batchSize, resolve, reject)
        })
      }
    
      function deleteQueryBatch (db, query, batchSize, resolve, reject) {
        query.get()
    .then((snapshot) => {
            // When there are no documents left, we are done
            if (snapshot.size === 0) {
              return 0
            }
    
          // Delete documents in a batch
          var batch = db.batch()
          snapshot.docs.forEach(function (doc) {
            batch.delete(doc.ref)
          })
    
          return batch.commit().then(function () {
            return snapshot.size
          })
        }).then(function (numDeleted) {
          if (numDeleted <= batchSize) {
            resolve()
            return
          }
          else {
          // Recurse on the next process tick, to avoid
          // exploding the stack.
          return process.nextTick(function () {
            deleteQueryBatch(db, query, batchSize, resolve, reject)
          })
        }
      })
        .catch(reject)
      }
    

    现在,我在firebase控制台中发现错误:

    referenceerror:未定义exampleid 在exports.deletecolletionfunction.functions.firestore.document.ondelete(/user_code/index.js:26:66) 在物体上。(/user_code/node_modules/firebase functions/lib/cloud functions.js:112:27) 下一个(本地) at/user-code/node-modules/firebase-functions/lib/cloud-functions.js:28:71 在等待程序中(/user_code/node_modules/firebase functions/lib/cloud functions.js:24:12) at cloudfunction(/user_code/node_modules/firebase functions/lib/cloud functions.js:82:36) at/var/tmp/worker/worker.js:728:24 在进程中。_tickdomaincallback(internal/process/next_tick.js:135:7)

    谢谢你的帮助!

    1 回复  |  直到 6 年前
        1
  •  1
  •   Diego P    6 年前

    改用 admin.initializeApp();