如何在firebase模拟器中测试删除集合(firebase_tools.firestore.delete与云通信,而不是模拟器)

laximzn5  于 2023-11-21  发布在  其他
关注(0)|答案(3)|浏览(111)

我试图在模拟器中测试一个firebase云函数。我已经能够在模拟器中CRUD firestore数据。我能够在模拟器中调用云函数。但我删除集合的函数是接触到google cloud,而不是在模拟器中执行操作。
要删除收藏,google建议你使用“firebase_tools”来执行操作(https://firebase.google.com/docs/firestore/solutions/delete-collections)。
下面是我在模拟器中运行的云函数的简化版本:

//Delete a firestore document.  
//When run in the emulator, this will successfully delete the piece of data in our emulator.
const paPath = FirebasePathUtils.getTeamPropertyAnalysisPath(pa.parentTeamId, pa.parentWorkspaceId, pa.id);
const p1 = admin.firestore().doc(paPath).delete();

//Delete all data in a collection.  
//When run in the emulator this IS REACHING OUT TO THE REAL CLOUD NOT USING THE EMULATOR.
const paDataPath = FirebasePathUtils.getTeamPropertyAnalysisDataPath(teamId, wsId, paId);
const pa2 = firebase_tools.firestore
   .delete(paDataPath, {
     project: process.env.GCLOUD_PROJECT,
     recursive: true,
     yes: true,
     token: functions.config().fb.token
   })
   .then( () => {
     console.log(`Successfully Deleted data under ${paDataPath}`);
   });

return Promise.all([p1, p2]);

字符串
当我在模拟器中运行cloud函数,并使用“firebase_toosl”执行删除集合代码时,我得到输出

Google API requested!
   - URL: "https://firestore.googleapis.com/v1beta1/projects/reitools-test/databases/(default)/documents/teamdata/-LjcN--jRrirOzDD0e3I/workspace_data/-LjcN-vktqOC8BJR_8X1/property_analyses_data/-LgJZf7GLRetC2fsVRvb"
   - Be careful, this may be a production service.
⚠  Google API requested!
   - URL: "https://firestore.googleapis.com/v1beta1/projects/reitools-test/databases/(default)/documents/teamdata/-LjcN--jRrirOzDD0e3I/workspace_data/-LjcN-vktqOC8BJR_8X1/property_analyses_data/-LgJZf7GLRetC2fsVRvb:runQuery"
   - Be careful, this may be a production service.


关于如何让“firebase_tools”在模拟器上执行它的操作,有什么想法吗?

cyvaqqii

cyvaqqii1#

我看到自从你发布你的问题已经8个月了。我希望你已经解决了你的问题。
如果没有,对于那些在这里登陆的人来说,问题在于你的环境变量“process.env.GCLOUD_PROJECT”。
我相信在你的测试中,你正在初始化一个类似的firestore示例:

firebase.initializeAdminApp({ projectId: 'deletetest' }).firestore()

字符串
在这种情况下,你应该用'deletetest'覆盖GCLOUD_PROJECT变量,它是你模拟的项目示例的projectId。
就这么简单

process.env.PROJECT_ID = 'deleteclub'


我认为Jest只会覆盖测试文件的变量,所以如果其他测试需要这个环境变量,它不会引起任何问题,当然,你需要在需要的地方覆盖每个测试。
我希望这会让人高兴:)
干杯!干杯!

mbzjlibv

mbzjlibv2#

这可能是非常晚,但我最近一直在努力解决这个问题,我得出的结论是,它可能不可能(尚未)测试云功能对模拟器(虽然我可能是错误的)。
但如果你只是想测试你的云函数,单元测试是一条路。我的解决方案是在Firebase中创建第二个'dev'项目。在我的index.js中,我用空参数初始化admin:

const functions = require("firebase-functions")
const admin = require("firebase-admin")
admin.initializeApp()

字符串
然后在我的单元测试文件(index.test.js)中,我使用从第二个'dev'项目下载的serviceAccountKey初始化我的测试环境。(在firebase控制台中,找到项目设置,然后是service accounts选项卡,然后生成新的serviceAccountKey)

const test = require("firebase-functions-test")({ 
    databaseURL: "'https://your-project-id.firebaseio.com",
    projectId: "your-project-id",
}, "path/to/serviceAccountKey.json")


所有测试都在Live 'dev'数据库上执行,该数据库没有升级到blaze计划。然而,由于serviceAccountKey仅在index.test.js文件中,因此当我运行firebase deploy时,函数(和安全规则)部署到我的生产项目中。
这样我就可以得到单元测试的所有好处,而不用担心破坏我的生产数据库,而且由于spark计划有如此慷慨的读/写限制,我怀疑我的开发项目将永远不会有超过这些限制的危险。
如果你找到了一种在模拟器中测试云函数的方法,请告诉我。如果你还没有找到解决方案,我希望我提供的选项能有所帮助。
P.S. firestore.recursiveDelete(docRef)无疑是删除集合(和子集合)的更好方法。
https://googleapis.dev/nodejs/firestore/latest/Firestore.html#recursiveDelete

vc9ivgsu

vc9ivgsu3#

import * as http from 'http'

// Adapted from https://github.com/firebase/firebase-js-sdk/blob/00235ba68fdbb5d9788a14ba2bdd75cad87301e4/packages/rules-unit-testing/src/impl/test_environment.ts#L105

export const clearFirestore(projectName: string) = async (): Promise<void> => {
  return new Promise((resolve: () => void, reject: (reason?: any) => void) => {
    http
      .request(
        {
          protocol: 'http:',
          host: '127.0.0.1',
          port: '9000',
          path: `/emulator/v1/projects/${projectName}/databases/(default)/documents`,
          method: 'DELETE',
        },
        function (res) {
          if (res.statusCode == 200) {
            resolve()
          } else {
            reject(`clearFirestore() failed: ${res.statusCode}`)
          }
        }
      )
      .on('error', (e) => {
        reject(e)
      })
      .end()
  })
}

字符串

相关问题