【问题标题】:Firestore new database - How do I backupFirestore 新数据库 - 如何备份
【发布时间】:2018-03-26 13:48:08
【问题描述】:

google firestore 数据库服务是否提供备份? 如果是,我该如何备份数据库,出现错误如何恢复?

【问题讨论】:

标签: backup google-cloud-firestore


【解决方案1】:

更新:现在可以使用 Cloud Firestore 管理的导出和导入服务备份和恢复 Firebase Firestore

你这样做:

  1. Create a Cloud Storage bucket for your project - 确保它是 us-central1 或 2 中的区域 / 多区域类型的存储桶

  2. 使用gcloud config set project [PROJECT_ID]为您的项目设置gcloud

导出

全部导出调用 gcloud firestore export gs://[BUCKET_NAME]导出特定集合使用 gcloud firestore export gs://[BUCKET_NAME] --collection-ids='[COLLECTION_ID_1]','[COLLECTION_ID_2]'

导入

全部导入调用 gcloud firestore import gs://[BUCKET_NAME]/[EXPORT_PREFIX]/ 其中 [BUCKET_NAME] 和 [EXPORT_PREFIX] 指向导出文件的位置。例如 - gcloud firestore import gs://exports-bucket/2017-05-25T23:54:39_76544/

通过调用

导入特定集合gcloud firestore import --collection-ids='[COLLECTION_ID_1]','[COLLECTION_ID_2]' gs://[BUCKET_NAME]/[EXPORT_PREFIX]/

这里有完整的说明: https://firebase.google.com/docs/firestore/manage-data/export-import

【讨论】:

【解决方案2】:

2018 年 7 月更新:Cloud Firestore 现在支持数据的托管导入和导出。有关详细信息,请参阅文档:

https://firebase.google.com/docs/firestore/manage-data/export-import


[Googler here] 不,目前我们不提供托管备份或导入/导出服务。这是我们将来肯定会提供的东西,只是我们还没有为最初的 Beta 版本做好准备。

现在最好的备份方法是使用我们的 Java/Python/Node.js/Go 服务器 SDK 编写您自己的脚本,从每个集合中下载所有文档并在需要时将它们写回应该相当简单到。

【讨论】:

  • 太好了。感谢您的评论 - 如果有人可以分享他们的代码(Node.js 获得额外奖励 :))
  • 我在尝试恢复大型数据集时遇到了速率限制。官方备份和恢复工具是否有时间表,理想情况下每个文档写入操作都不需要 api 请求?
  • @ForrestLyman 你试过batched writes吗?
  • @hakatashi Firebase 现在原生支持它。见我上面的回答。
  • 是否可以像 Firebase RT DB 中那样进行每日备份?此处随附的 firebase 指南描述了如何进行单次备份,我想配置每日备份。
【解决方案3】:

https://www.npmjs.com/package/firestore-backup

是为此而创建的工具。

(我没有创建它,只是在这里添加它,因为人们会发现这个问题)

【讨论】:

  • 该工具似乎没有任何恢复 Firestore 数据库的功能
【解决方案4】:

我正在使用以下解决方法来进行每日 Firestore 备份:

我全局安装了这个:https://www.npmjs.com/package/firestore-backup-restore

我有一个如下所示的 cron 作业:

0 12 * * *  cd ~/my/backup/script/folder && ./backup-script.sh

我的 backup-script.sh 看起来像这样:

#!/bin/sh

. ~/.bash_profile

export PATH=/usr/local/bin/

dt=$(/bin/date '+%d-%m-%Y %H:%M:%S');
echo "starting backup for $dt"
firestore-backup-restore -a ~/path/to/account/credentials/file.json -B ./backups/"$dt"

【讨论】:

    【解决方案5】:

    本地备份

    1. firestore-import-export

    这是我用于“一次性”本地备份的方法,也是我通常推荐的方法。 (如果你想要一个 JSON 文件,最直接)

    1. firestore-backup-restore

    缺点:

    1. 很久没更新了。

    其他选项:(不推荐)

    1. python-firebase-admin-firestore-backup

    缺点:

    1. 仅备份;无法从它创建的备份中恢复。
    2. 很久没更新了。
    1. firestore-backup

    缺点:

    1. 仅备份;无法从它创建的备份中恢复。

    云备份

    1. 官方gcloud backup commands

    缺点:

    1. 备份文件难以解析/不可行。 (更新:如何convert to a json file
    2. 您必须设置gcloud cli。 (更新:或使用cloud shell 运行命令)
    3. 它不在本地备份;相反,它备份到云,you can then download。 (也可以被认为是一种优势,这取决于你想要什么)

    请注意,对于 gcloud backup 命令,您有多种选择如何安排它们自动运行。一些选项是shown here

    【讨论】:

      【解决方案6】:

      我编写了一个工具,它可以遍历数据库的集合/文档并将所有内容导出到单个 json 文件中。此外,它还将导入相同的结构(有助于克隆/移动 Firestore 数据库)。它作为 NPM 包发布。随意尝试并提供一些反馈。

      https://www.npmjs.com/package/node-firestore-import-export

      【讨论】:

        【解决方案7】:

        我遇到了同样的问题,并创建了一个小型 npm 包,它允许您使用 Cloud Functions 创建计划备份。它使用 Firestore 的新导入/导出功能。

        const firestoreBackup = require('simple-firestore-backup')
        exports.firestore_backup = functions.pubsub.schedule('every 24 hours').onRun(firestoreBackup.createBackupHandler())
        

        查看完整的readme 以了解如何设置,超级简单!

        【讨论】:

          【解决方案8】:

          使用 Python 2 的解决方案。

          https://github.com/RobinManoli/python-firebase-admin-firestore-backup上叉它

          首先安装和设置 Firebase Admin Python SDK:https://firebase.google.com/docs/admin/setup

          然后安装到你的python环境中:

          pip install firebase-admin
          

          安装 Firestore 模块:

          pip install google-cloud-core
          pip install google-cloud-firestore
          

          (来自ImportError: Failed to import the Cloud Firestore library for Python

          Python 代码

          # -*- coding: UTF-8 -*-
          
          import firebase_admin
          from firebase_admin import credentials, firestore
          import json
          
          cred = credentials.Certificate('xxxxx-adminsdk-xxxxx-xxxxxxx.json') # from firebase project settings
          default_app = firebase_admin.initialize_app(cred, {
              'databaseURL' : 'https://xxxxx.firebaseio.com'
          })
          
          db = firebase_admin.firestore.client()
          
          # add your collections manually
          collection_names = ['myFirstCollection', 'mySecondCollection']
          collections = dict()
          dict4json = dict()
          n_documents = 0
          
          for collection in collection_names:
              collections[collection] = db.collection(collection).get()
              dict4json[collection] = {}
              for document in collections[collection]:
                  docdict = document.to_dict()
                  dict4json[collection][document.id] = docdict
                  n_documents += 1
          
          jsonfromdict = json.dumps(dict4json)
          
          path_filename = "/mypath/databases/firestore.json"
          print "Downloaded %d collections, %d documents and now writing %d json characters to %s" % ( len(collection_names), n_documents, len(jsonfromdict), path_filename )
          with open(path_filename, 'w') as the_file:
              the_file.write(jsonfromdict)
          

          【讨论】:

          • 已经有一个内置的本地解决方案可以从命令行备份/恢复。
          • 什么是内置的原生解决方案?有些人可能不想乱用云存储桶,特别是如果他们想处理数据。看不到否决票的原因。就我而言,当我来到这里时,我会更喜欢 python 解决方案。
          【解决方案9】:

          这是我的 Android Java 代码,用于轻松获取任何 Fire Store 数据收集的备份

          首先使用此方法读取采集数据并存储到移动设备存储中的序列化文件中

          private void readCollection(){
                  ServerSide.db.collection("Collection_name")
                          .get()
                          .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
                              @Override
                              public void onComplete(@NonNull Task<QuerySnapshot> task) {
                                  if (task.isSuccessful()) {
                                      HashMap alldata = new HashMap();
                                      for (QueryDocumentSnapshot document : task.getResult()) {
                                          alldata.put(document.getId(),document.getData());
          //                                ServerSide.db.collection("A_Sentences_test").document(document.getId())
          //                                        .set(document.getData());
                                      }
                                      try {
                                          FileOutputStream fos = openFileOutput("filename.txt", Context.MODE_PRIVATE);
                                          ObjectOutputStream os = new ObjectOutputStream(fos);
                                          os.writeObject(alldata);
                                          os.close();
                                          fos.close();
                                          Toast.makeText(MainActivity.this, "Stored", Toast.LENGTH_SHORT).show();
          
                                          FileInputStream fis = openFileInput("filename.txt");
                                          ObjectInputStream is = new ObjectInputStream(fis);
                                          HashMap ad = (HashMap) is.readObject();
                                          is.close();
                                          fis.close();
                                          Log.w("All data",ad+" ");
          
                                      }catch (Exception e){
                                          Log.w("errrrrrrrr",e+"");
                                      }
                                  } else {
                                      Log.d("Colllllllllll", "Error getting documents: ", task.getException());
                                  }
                              }
                          });
              }
          

          之后可以通过logcat查看数据是否序列化正确。这是恢复代码

          private void writeData(){
                  try {
                      FileInputStream fis = openFileInput("filename.txt");
                      ObjectInputStream is = new ObjectInputStream(fis);
                      HashMap ad = (HashMap) is.readObject();
                      is.close();
                      fis.close();
                      for (Object s : ad.keySet()){
                          ServerSide.db.collection("Collection_name").document(s.toString())
                                  .set(ad.get(s));
                      }
                      Log.w("ddddddddd",ad+" ");
                  }catch (Exception e){
                      e.printStackTrace();
                  }
              }
          

          希望这会有所帮助

          【讨论】:

            【解决方案10】:

            问题很老,项目很好,但我对备份有些顾虑。

            1-对于 blaze plan 用户(免费)官方解决方案是禁止的。

            2-由于免费用户每天有 50k 的读取配额,因此该限制在实时数据库和大型数据库中可能是个问题。

            3-据我研究,大多数项目没有时间限制左右,每次运行时都会下载相同的数据。

            4-将集合保存为文件夹并将每个文档保存为单独的文件并仅获取更新的文档并直接替换文件不是更好吗?

            我可能会实施自己的解决方案,但只是想知道您的想法:)

            【讨论】:

              猜你喜欢
              • 2018-10-25
              • 2011-10-31
              • 2014-01-29
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-07-14
              相关资源
              最近更新 更多