将Firebase实时数据库迁移到Firestore

时间:2017-10-04 19:18:29

标签: firebase firebase-realtime-database google-cloud-firestore

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

4 个答案:

答案 0 :(得分:8)

我编写了一个小节点脚本,以快速而肮脏的方式迁移事物,并且工作得非常好。

如果其他人感兴趣的话,它就在下面。

注意:仅当实时数据库中的数据模型完全平坦并且没有太多嵌套数据,并且您打算在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);
  });
}

答案 1 :(得分: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');
  });
}
  1. 如果您的计算机上没有Node-Js,请用Google进行安装。并不难。
  2. 您可以从Firebase控制台下载firestore-config.json

答案 2 :(得分:0)

我只是用一个非常基本的节点脚本来完成此操作,希望它可以作为下一个有此问题的示例的示例:

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!')
})

当然,您也可以为每个用户进行两次迭代,但是在我的情况下则不需要:)

答案 3 :(得分:-1)

您好我已经为同一个

创建了一个脚本
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) => { }); }); });}