导出 Firestore 备份数据的云功能。使用 firebase-admin 或 @google-cloud/firestore?

Posted

技术标签:

【中文标题】导出 Firestore 备份数据的云功能。使用 firebase-admin 或 @google-cloud/firestore?【英文标题】:Cloud function to export Firestore backup data. Using firebase-admin or @google-cloud/firestore? 【发布时间】:2019-12-22 01:14:20 【问题描述】:

我目前正在尝试构建一个云功能来将我的 Firestore 数据导出到我的存储桶。

我在 Firebase 文档中找到的关于如何执行此操作的唯一示例:

https://googleapis.dev/nodejs/firestore/latest/v1.FirestoreAdminClient.html#exportDocuments

示例

const firestore = require('@google-cloud/firestore');

const client = new firestore.v1.FirestoreAdminClient(
  // optional auth parameters.
);

const formattedName = client.databasePath('[PROJECT]', '[DATABASE]');
client.exportDocuments(name: formattedName)
  .then(responses => 
    const response = responses[0];
    // doThingsWith(response)
  )
  .catch(err => 
    console.error(err);
  );

从那个例子来看,我似乎需要安装 @google-cloud/firestore 作为我的云函数的依赖项。

但我想知道是否可以使用firebase-admin 包访问这些方法。

我想到了这一点,因为 firebase-admin 已经将 @google-cloud/firestore 作为依赖项。

> firebase-admin > package.json

"dependencies": 
    "@firebase/database": "^0.4.7",
    "@google-cloud/firestore": "^2.0.0",    // <---------------------
    "@google-cloud/storage": "^3.0.2",
    "@types/node": "^8.0.53",
    "dicer": "^0.3.0",
    "jsonwebtoken": "8.1.0",
    "node-forge": "0.7.4"
  ,

问题:

是否可以仅使用firebase-admin 获取FirestoreAdminClient 的实例并使用exportDocuments 方法?

或者我真的需要将@google-cloud/firestore 安装为直接依赖项并直接使用它吗?

【问题讨论】:

【参考方案1】:

据我所知,您访问管理客户端的方式是正确的。

const client = new admin.firestore.v1.FirestoreAdminClient();

但是,由于 Firestore 库实际上并未定义 v1 RPC 的详细类型,因此您可能不会获得任何 TypeScript/intellisense 帮助。注意它们是如何用any 类型声明的:https://github.com/googleapis/nodejs-firestore/blob/425bf3d3f5ecab66fcecf5373e8dd03b73bb46ad/types/firestore.d.ts#L1354-L1364

【讨论】:

它确实有效!没有智能感知(根据您指出的原因)。但它有效。谢谢。 你可以做这样的事情来让 TypeScript/intellisense 工作(仅限 TypeScript,对不起 Flow 用户:/)import FirestoreAdminClient from '@google-cloud/firestore/build/src/v1/firestore_admin_client';const FirestoreV1AdminClient = admin.firestore.v1.FirestoreAdminClient as typeof FirestoreAdminClient;【参考方案2】:

这是我正在使用的一个实现,它允许您根据 firebase 在此处https://firebase.google.com/docs/firestore/solutions/schedule-export 提供的模板执行您需要执行的任何操作。

在我的情况下,我正在过滤来自 firestore 的集合,我不希望调度程序自动备份

const  Firestore  = require('@google-cloud/firestore')

const firestore = new Firestore()
const client = new Firestore.v1.FirestoreAdminClient()
const bucket = 'gs://backups-user-data'

exports.scheduledFirestoreBackupUserData = async (event, context) => 
  const databaseName = client.databasePath(
    process.env.GCLOUD_PROJECT,
    '(default)'
  )

  const collectionsToExclude = ['_welcome', 'eventIds', 'analyticsData']

  const collectionsToBackup = await firestore.listCollections()
    .then(collectionRefs => 
      return collectionRefs
        .map(ref => ref.id)
        .filter(id => !collectionsToExclude.includes(id))
    )


  return client
    .exportDocuments(
      name: databaseName,
      outputUriPrefix: bucket,
      // Leave collectionIds empty to export all collections
      // or define a list of collection IDs:
      // collectionIds: ['users', 'posts']
      collectionIds: [...collectionsToBackup]
    )
    .then(responses => 
      const response = responses[0]
      console.log(`Operation Name: $response['name']`)
      return response
    )
    .catch(err => 
      console.error(err)
    )

【讨论】:

请注意,在 Node10 运行时,变量 process.env.GCLOUD_PROJECT 似乎默认不可用并且脚本不会运行。 @Vojtěch 可能是这种情况,是的,因为我目前的功能仍在节点 8 上运行...如果您找到修复方法,请告诉我。 我只是手动将云项目 ID 作为 env var 传递,它可以工作, 您直接返回异步函数并且该函数立即完成,即使导出操作仍在运行。不应该有某种return await client.exportDocuments(... 来防止这种行为吗? 在定义函数时,只需将 GCLOUD_PROJECT 与您的 projectId 作为环境变量添加。【参考方案3】:

firebase-admin 只是包装 Cloud SDK 并重新导出其符号。您可以使用包装器,或者直接使用 Cloud SDK,或者如果需要,甚至可以将两者结合使用。如果您想同时使用两者,则必须声明对 @google-cloud/firestore 的显式依赖,以便能够将其直接导入到您的代码中。

【讨论】:

如果可以,您介意向我展示一个如何使用firebase-admin 获取FirestoreAdminClient 的示例吗?我试过:const client = new admin.firestore.v1.FirestoreAdminClient();,这一切都是由 VSCode 自动完成的。但在那之后我的client 变量没有自动完成。难道我做错了什么?谢谢! 我从未使用过 FirestoreAdminClient。典型的访问将通过 Firestore 对象进行。 googleapis.dev/nodejs/firestore/latest/Firestore.html【参考方案4】:

这是关于如何通过混合 Cloud Scheduler、PubSub 和 Firebase 函数https://firebase.google.com/docs/firestore/solutions/schedule-export 进行自动 Firestore 备份的完整代码解释(我使用它并且效果很好)

【讨论】:

以上是关于导出 Firestore 备份数据的云功能。使用 firebase-admin 或 @google-cloud/firestore?的主要内容,如果未能解决你的问题,请参考以下文章

有没有办法只导出Firestore增量或自上次导出后的更改(差异)?

从 Firestore 导出 json

Firestore 中的重复文档可以通过文档编辑的云功能进行更新吗?

有时我的云函数会从 Firestore 返回旧数据。是缓存问题吗?

将数据从 Firestore 加载到 BigQuery 的适当方法是啥?

云功能有时会在触发另一个云功能后写入 FireStore