将 Firebase 实时数据库迁移到 Firestore

Posted

技术标签:

【中文标题】将 Firebase 实时数据库迁移到 Firestore【英文标题】:Migrate Firebase Realtime Database to Firestore 【发布时间】:2018-03-16 07:15:00 【问题描述】:

我正在寻找将使用 firebase 实时数据库的应用程序数据库迁移到新的 Cloud Firestore 数据库的最佳方法。我对我正在从事的项目充满信心,我不需要进行任何数据架构更改,所以我几乎只是尝试 1-1 映射它。 Firebase 在他们的网站上建议只编写一个脚本来执行此操作,但我不确定最好的方法。有没有人已经编写了一个脚本来完成这个?

【问题讨论】:

firebase.google.com/docs/firestore/firestore-for-rtdb 是的,知道那个链接,但他们基本上只是建议写一个脚本,但这不是这个问题要问的。 不太可能有人会为此编写通用脚本,因为它可能会根据每个人的特定用例和要求进行定制。 “要求我们推荐或查找书籍、工具、软件库、教程或其他场外资源的问题对于 Stack Overflow 来说是无关紧要的,因为它们往往会吸引固执己见的答案和垃圾邮件。相反,描述问题以及迄今为止为解决问题所做的工作。” 你能链接到他们提到你可以写一个脚本来做的地方吗? 【参考方案1】:

我只是用一个非常基本的节点脚本做到了这一点,我希望它可以作为下一个遇到此问题的示例:

require('firebase/firestore')
const fs = require('fs')
const  initializeApp, firestore  = require('firebase/app')

const UID = 'asdfasdf' // UID of the user you are migrating

initializeApp(
    apiKey: process.env.API_KEY,
    projectId: process.env.PROJECT_ID
)

// db.json is the downloaded copy from my firebasedatabase
fs.readFile('db.json', (err, data) => 
    if (err) throw err
    const json = JSON.parse(data)
    const readings = json.readings[UID]
    const result = Object.values(readings)
    result.forEach(( book, chapter, date ) =>
        // In my case the migration was easy, I just wanted to move user's readings to their own collection
        firestore().collection(`users/$UID/readings`)
            .add( date: firestore.Timestamp.fromDate(new Date(date)), chapter, book )
            .catch(console.error)
    )
    console.log('SUCCESS!')
)

当然,您也可以为每个用户重复两次,但在我的情况下,它不是必需的 :)

【讨论】:

【参考方案2】:

实际上,我在Node-Js 中写了一个脚本,使用批处理写入Firestore(批处理超级快,适合写入可能的项目) 这是我的代码,只需将文件名更改为您的名称并运行node YOUR_FILE_NAME.js

const admin = require('firebase-admin');
var serviceAccount = require('./firestore-config.json');
var database = require('./database.json');

admin.initializeApp(
  credential: admin.credential.cert(serviceAccount),
  databaseURL: 'YOUR_FILE_STORE_DB_URL',
);

var db = admin.firestore();
var allEntityNames = Object.keys(database);
var counter = 0;
var commitCounter = 0;
var batches = [];
batches[commitCounter] = db.batch();
var ref = db.collection('users');
allEntityNames.forEach(function(k, i) 
  if (counter <= 498) 
    var thisRef = ref.doc(k);
    batches[commitCounter].set(thisRef, database[k]);
    counter = counter + 1;
   else 
    counter = 0;
    commitCounter = commitCounter + 1;
    batches[commitCounter] = db.batch();
  
);
for (var i = 0; i < batches.length; i++) 
  batches[i].commit().then(function() 
    console.count('wrote batch');
  );

    如果你的机器上没有Node-Js,谷歌安装它。没那么难。 您可以从 Firebase 控制台下载 firestore-config.json

【讨论】:

【参考方案3】:

您好,我已经为此创建了一个脚本

import  AngularFirestore, AngularFirestoreCollection  from 'angularfire2/firestore'; 
import  AngularFireDatabase  from 'angularfire2/database';
constructor( private afs: AngularFirestore, private angularfire: AngularFireDatabase ) 
convert()  
this.itemsCollection = this.afs.collection('requests');//ref() 
this.angularfire.list('/requests/').auditTrail().subscribe((data: any) =>  
_.each(data, element =>
this.itemsCollection.doc(element.key).set(element.payload.val()) .then((result) =>  ); ); );

【讨论】:

你可以添加步骤来运行它吗? yes 1) 配置您的 firebase 项目,然后 2) 添加 TS 文件 import AngularFirestore, AngularFirestoreCollection from 'angularfire2/firestore';从 'angularfire2/database' 导入 AngularFireDatabase ;构造函数(私有 afs:AngularFirestore,私有 angularfire:AngularFireDatabase) convert() this.itemsCollection = this.afs.collection('requests');//ref() this.angularfire.list('/requests/') .auditTrail().subscribe((data: any) => _.each(data, element => this.itemsCollection.doc(element.key).set(element.payload.val()) .then((结果) => ); ); );【参考方案4】:

我写了一个小节点脚本,它以一种快速而肮脏的方式迁移东西,而且效果很好。

如果其他人有兴趣,请在下面。

注意:只有在实时数据库中的数据模型完全平坦且没有太多嵌套数据并且您打算在 Firestore 中保持数据平坦时才应使用此方法

要运行此脚本,只需创建一个名为 index.js 的节点文件,并将其与您的服务帐户文件和来自实时数据库导出的原始 json 文件一起放入目录中,然后从命令行运行以下命令。

$ node index.js

下面的脚本实现。

const admin = require('firebase-admin');

var serviceAccount = require("./config.json");
var database = require("./database.json");
var async = require ('async');

admin.initializeApp(
  credential: admin.credential.cert(serviceAccount)
);

var db = admin.firestore();

var allEntityNames = Object.keys(database);

var asyncTasks = [];

for (var i in allEntityNames) 
  var entityName = allEntityNames[i];
  var entity = database[entityName];
  var entityKeys = Object.keys(entity);

  console.log("began migrating "+ entityName);
  for (var j in entityKeys) 
    var entityKey = entityKeys[j];
    var dict = entity[entityKey];
    asyncTasks.push(function(callback)
      db.collection(entityName).doc(entityKey).set(dict)
        .then(function() 
          callback();
        )
        .catch(function(error) 
          console.log(error);
          callback();
        );
    );
  
  async.parallel(asyncTasks, function()
    console.log("Finished migrating "+ entityName);
  );

【讨论】:

以上是关于将 Firebase 实时数据库迁移到 Firestore的主要内容,如果未能解决你的问题,请参考以下文章

如何为firebase字段添加价值

使用Node,EJS和Firebase进行实时数据库模板化

将 mySQL 迁移到 Firebase [关闭]

如何将我的 Firebase 实时数据库转移到 Firebase Cloud Firestore

如何将我的 Firebase 实时数据库转移到 Firebase Cloud Firestore

我应该将我的 firebase 数据库迁移到 firestore 数据库吗?