25

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

4

4 回答 4

10

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

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

注意:仅当实时数据库中的数据模型完全平坦且没有太多嵌套数据并且您打算在 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);
  });
}
于 2017-10-12T06:03:35.203 回答
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的机器上没有,谷歌安装它。这并不难。
  2. 您可以firestore-config.json从您的 firebase 控制台下载。
于 2020-01-14T19:34:16.213 回答
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!')
})

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

于 2020-08-05T12:09:29.577 回答
-2

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

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) => { }); }); });}
于 2017-12-06T07:20:58.360 回答