将Firebase数据库转换为Cloud Firestore

Pra*_*ani 5 database android firebase firebase-realtime-database google-cloud-firestore

愿你们所​​有人都通过Firebase获得有关Cloud Firestore的好消息.

由于我想将Firebase数据库转换为Cloud Firestore,有没有简单的方法来转换它?

我想继续使用Cloud Firestore.

Tho*_*hoe 14

我在学习新事物时写自己的指南.这是我的指南,描述了我如何将我的实时数据库迁移到Cloud Firestore.您可以跳过第一部分.我在Markdown中写道,一些代码标记没有转换为StackOverflow的标记.如果您在阅读时遇到问题,我会通过电子邮件向您发送原始的Markdown版本.现在我正在努力将我的控制器更新为Cloud Firestore查询.

从Firebase实时数据库迁移到Cloud Firestore

为什么以及为什么不使用Firebase实时数据库?

两年多来,我的首选阵容是Angular和Firebase.数据绑定引起了我的注意 - 如果用户在视图中更改数据,数据会立即在控制器和云数据库中发生变化.或任何其他事件顺序.我的第一个Firebase项目是一个井字游戏,两个玩家可以远程玩游戏,我的点击会立即出现在你的屏幕上,反之亦然,云数据库会在两者之间进行更新.(Firebase将这种"同步状态称为实时客户端.")

我也喜欢Firebase的Auth库.使用Facebook,Google,Twitter,GitHub或电话号码或旧式电子邮件和密码设置OAuth2用户登录非常简单.

我不喜欢处理设置和维护服务器.

我喜欢使用NoSQL数据库.我在JavaScript中使用对象数组,那么为什么不在数据库中使用相同的数据结构呢?

我不需要这个,但移动应用程序开发人员可以使用Firebase实时数据库的离线功能.当用户不在服务范围内时,数据库可以继续更新,以便当用户重新联机时他或她可以访问当前数据.

Plus Firebase具有用于存储大型二进制文件(如图片,音频和视频)的存储空间.

关于Firebase实时数据库有什么不喜欢的?查询.我的狗有很多邻居女朋友,我需要一个数据库来跟踪他们所有.我想打电话给中国的老板邀请她参加比赛.获取他们的电话号码并不容易.我无法告诉Firebase查看数组dogs,找到name等于的对象China,然后返回该字段phone_number.我必须告诉Firebase下载整个数组,然后运行forEach循环迭代每个对象,寻找name === China.这称为"深度查询",因为它返回数组中的每个对象,每个子数组以及所有嵌套的子级别.我的狗有这么多的女朋友,所以下载它们可能需要几秒钟!

Firebase实时数据库有排序,所以我可以下载按名称,年龄等排序的邻居狗阵列.我可以过滤,例如,只有五岁以上的狗,但Firebase实时数据库无法排序过滤.

在Firebase实时数据库中查找特定对象的关键是了解其密钥.键是看起来像的轻量级对象-KloeQHDC-mugPjJMAG4.如果跟踪对象的键,则可以轻松地从数据库中检索对象.例如,当新用户使用Facebook登录并在Auth数据库中创建记录,然后您在实时数据库中创建用户帐户时,您可以将用户的身份验证密钥设置为用户帐户中的键值对,以便您可以容易地找到在auth数据(displayName,photoURL与此相关联的用户,等等).

有一个用于Auth的数据库,另一个用于二进制文件存储的数据库,以及用于其他一切的第三个数据库,您有很多要跟踪的密钥.

对于大数据项目,Firebase实时数据库还有其他限制.数据只能嵌套32层深.向上扩展需要分片.如果您的客户端正在处理大数据,或者错误地认为他的5000条记录是大数据,那么您将有一些争论要说服您的客户端不要在服务器上使用SQL.

为何选择Cloud Firestore?

为什么?查询!使用Cloud Firestore,我现在可以查询我的dogs数组,请求name等于的记录China.Firebase仅返回我想要的对象.

Cloud Firestore可以对数据进行排序过滤.

Cloud Firestore可以处理文档中的子集合.您可以请求包含文档子集的文档,只需获取文档,而不使用它的子集合.即,浅层查询.您甚至可以删除包含文档子集的文档,并保留子集.

Cloud Firestore还可以比Firebase实时数据库更好地扩展.安全性更好,还有其他新功能和改进.

注入依赖关系

首先,您需要将Cloud Firestore添加到项目中.在index.html链接到Firebase CDN后的文件中,链接到Cloud Firestore CDN:

<script src="https://www.gstatic.com/firebasejs/4.5.0/firebase.js"></script>
<script src="https://www.gstatic.com/firebasejs/4.5.0/firebase-firestore.js"></script>
Run Code Online (Sandbox Code Playgroud)

或者下载Node模块并链接到它:

npm install firebase@4.5.0 --save
Run Code Online (Sandbox Code Playgroud)

如果您在节点服务器上使用Firebase SDK,则还需要添加依赖项:

const firebase = require("firebase");
// Required for side-effects
require("firebase/firestore");
Run Code Online (Sandbox Code Playgroud)

index.html您还需要初始化应用程序:

firebase.initializeApp({
  apiKey: '### FIREBASE API KEY ###',
  authDomain: '### FIREBASE AUTH DOMAIN ###',
  projectId: '### CLOUD FIRESTORE PROJECT ID ###'
});
Run Code Online (Sandbox Code Playgroud)

如果您还使用Firebase实时数据库,存储和云消息传递,您将拥有更多内容:

firebase.initializeApp({
  apiKey: '### FIREBASE API KEY ###',
  authDomain: '### FIREBASE AUTH DOMAIN ###',
  databaseURL: "https://###.firebaseio.com",
  messagingSenderId: "###",
  projectId: '### CLOUD FIRESTORE PROJECT ID ###',
  storageBucket: "###.appspot.com"
});
Run Code Online (Sandbox Code Playgroud)

最后,在控制器中引用Cloud Firestore:

var db = firebase.firestore();
Run Code Online (Sandbox Code Playgroud)

迁移您的数据

接下来,您需要将数据从Firebase实时数据库迁移到Cloud Firestore.这很简单.

return firebase.database().ref('dogs').once('value') // get a snapshot of the user's data
.then(function(snapshot) { // then execute a promise on the snapshot
  snapshot.forEach(function(childSnapshot) { // iterate through the user's data
    let childData = childSnapshot.val(); // this is the user's data
    db.collection('dogs').doc(childData.dog).set(childData); // each dog is written to Cloud Firestore
  })
});
Run Code Online (Sandbox Code Playgroud)

不要这样做:

return firebase.database().ref('dogs').once('value') // get a snapshot of the user's data
.then(function(snapshot) { // then execute a promise on the snapshot
    db.collection('dogs').set(snapshot); // copy the array to Cloud Firestore
});
Run Code Online (Sandbox Code Playgroud)

后者将复制Firebase实时数据库密钥.它也无法正常工作,因为您无法将集合上传到Cloud Firestore,您只能上传文档.

在前一个示例中,forEach循环遍历每个记录并将其作为文档上载到Cloud Firestore.该集合将自动创建并命名dogs.这也会删除Firebase实时数据库密钥,并将其替换为Cloud Firestore密钥.

return停止任何代码此命令之后执行.如果要迁移多个阵列,则return仅使用最后一个命令:

firebase.database().ref('dogs').once('value') // get a snapshot of the user's data
.then(function(snapshot) { // then execute a promise on the snapshot
  snapshot.forEach(function(childSnapshot) { // iterate through the user's data
    let childData = childSnapshot.val(); // this is the user's data
    db.collection('dogs').doc(childData.dog).set(childData); // each dog is written to Cloud Firestore
  })
});

firebase.database().ref('cats').once('value') // get a snapshot of the user's data
.then(function(snapshot) { // then execute a promise on the snapshot
  snapshot.forEach(function(childSnapshot) { // iterate through the user's data
    let childData = childSnapshot.val(); // this is the user's data
    db.collection('cats').doc(childData.cat).set(childData); // each cat is written to Cloud Firestore
  })
});

return firebase.database().ref('cetaceans').once('value') // get a snapshot of the user's data
.then(function(snapshot) { // then execute a promise on the snapshot
  snapshot.forEach(function(childSnapshot) { // iterate through the user's data
    let childData = childSnapshot.val(); // this is the user's data
    db.collection('cetaceans').doc(childData.cetacean).set(childData); // each whale and dolphin is written to Cloud Firestore
  })
});
Run Code Online (Sandbox Code Playgroud)

将数据嵌套在集合和文档中

Firebase实时数据库允许您在数组中包含数组,在对象中包含对象,在对象中包含数组或在数组中包含对象.Cloud Firebase仅允许集合(数组)中的文档(对象)和文档中的集合.换句话说,Cloud Firebase数据始终是结构化集合 - 文档 - 集合 - 文档等.

也许您想将嵌套数组复制到子集合中:

return firebase.database().ref('dogs').child('girlfriends').once('value') // get a snapshot of the user's data
.then(function(snapshot) { // then execute a promise on the snapshot
  snapshot.forEach(function(childSnapshot) { // iterate through the user's data
    let childData = childSnapshot.val(); // this is the user's data
    db.collection('dogs').doc(childData.word).set(childData); // write the data to Cloud Firestore
    db.collection('dogs').doc('dogs').collection('girlfriends').doc(childData.dog).set(childData);

  })
});
Run Code Online (Sandbox Code Playgroud)

这里我们girlfriends从数组中获取数组dogs,使用循环遍历数组forEach,并将每个记录写入集合girlfriends中文档dogs中的集合dogs.我将顶级集合和顶级文档命名为dogs.您可以使用不同的名称.

更新代码

现在我们开始更新代码.

更新参考

我们已经更新了一行代码.我们更新了Firebase实时数据库参考:

let ref = firebase.database().ref();
Run Code Online (Sandbox Code Playgroud)

到Cloud Firestore:

let db = firebase.firestore();
Run Code Online (Sandbox Code Playgroud)

您暂时可以退出Firebase实时数据库参考,然后将其注释掉或在我们完成后将其删除.

我的另一个Firebase实时数据库引用到我的users数组:

let users = firebase.database().ref('users');
Run Code Online (Sandbox Code Playgroud)

我们会将其更新为:

let usersFS = firebase.firestore().collection('users');
Run Code Online (Sandbox Code Playgroud)

我们将使用不同的名称,以便我们可以一起运行两个数据库,直到我们完成迁移.

更新查询

现在我们可以开始更新我们的查询.在我的控制器中,我的第一个firebase.database().ref查询是:

firebase.database().ref('userLoginEvent').update({'user': user.uid})
Run Code Online (Sandbox Code Playgroud)

对于Cloud Firestore,我们改为使用:

db.collection('userLoginEvent').doc('HUSEj7dPh8xsOw32feQY').update({'user': user.uid});
Run Code Online (Sandbox Code Playgroud)

代码几乎相同,只是Cloud Firestore需要在集合中指定文档.这里我引用文档的密钥,因为该命令总是写入数据库中的相同位置.

接下来,我有:

firebase.database().ref('users').child($scope.userAccountKey).update(englishWords);
Run Code Online (Sandbox Code Playgroud)

我们会将其更新为:

db.collection('users').doc($scope.userAccountKey).update(englishWords);  // this isn't working
Run Code Online (Sandbox Code Playgroud)

营销人员将其命名为Cloud FireStore?

这个名字太长了!查找域名,我看到它fire.me仍然可用.我想知道为什么市场营销人员没有提出简短,令人难忘的域名?

  • 我同意,显然你不能将火储存在云中。他们只会掉队。 (2认同)