我正在考虑使用 Firebase 使用 PhoneGap 和 HTML5 应用程序缓存编写移动应用程序。
让我们假设每个用户都有一个 TODO 项目列表。如果应用程序在手机离线时启动,它是否能够从上一个会话中加载数据并在建立连接时同步?如果是这样,我想知道这是如何实现的,因为我在 firebase.js 中找不到对 localStorage 的引用。
我正在考虑使用 Firebase 使用 PhoneGap 和 HTML5 应用程序缓存编写移动应用程序。
让我们假设每个用户都有一个 TODO 项目列表。如果应用程序在手机离线时启动,它是否能够从上一个会话中加载数据并在建立连接时同步?如果是这样,我想知道这是如何实现的,因为我在 firebase.js 中找不到对 localStorage 的引用。
简短的回答是:还没有。
一旦应用程序连接到 Firebase,客户端将在本地缓存数据,并且即使在网络连接丢失后也能够访问存在未完成的“on”回调的数据。但是,这些数据不会保存到磁盘,“离线模式”只会在应用程序仍在运行时工作。
未来将提供完整的离线支持。
2016 年编辑:现在可以对原生 iOS 和 Android 应用程序进行完全离线支持:https ://www.firebase.com/blog/2015-05-29-announcing-mobile-offline-support.html
为 JS 应用程序解决此问题的 Firebase 替代方案是 CouchDb(服务器)<=> PouchDb(JS 客户端)。如果你已经实现了一个干净整洁的客户端服务层,那么移植到 PouchDb 应该是相当简单的,因为它们都是 NoSQL/JSON 数据库。CouchDb 还支持索引的 map/reduce 视图。
PouchDb 是一个 Javascript API,它实现了一个完全离线的CouchDb 客户端。它可以自动检测并使用本地存储、IndexDb或WebSQL来在在线或离线时永久保存本地数据。PouchDb API 可用于访问本地或远程数据库(只需更改 URL)并在两者之间连接完全同步或过滤同步。有许多有用的 PouchDb 插件、代码示例和一个小型包装库来支持 AngularJS 的 Q Promise API。
使用 PouchDb,您可以在离线时安全地启动您的应用程序,然后在几天后重新启动您的应用程序并将所有 CUD 数据更改同步到服务器。这可能会导致更新冲突,因此 CouchDb 支持旨在检测和跟踪这种情况的记录版本控制。因此,您可能需要服务器端逻辑来解决这些冲突。这对于具有离线同步和 CouchDb 关键特性的分布式系统来说是不可避免的。我不确定 Firebase 是否支持此 MVCC 功能。
PouchDb 基本上是 Apache CouchDb 的重新实现,包括它的同步协议。CouchDb 和 PouchDb 都经过良好测试,免费且开源。开源意味着 CouchDb 服务器也可以部署为 Intranet 服务 - 可选择同步到外部云服务。有许多 CouchDb 托管服务提供商。
IBM 的 Cloudant 托管团队最近将他们的 BigCouch 集群功能添加到 Apache CouchDb 2.0 项目中,因此现在您可以从 Micro Db (PouchDb) => Single Server => Multi-Master (Replicated) => Big Couch Clustered / Geo Clustered 进行扩展。与 MongoDb 不同,CouchDb 安全地支持单服务器部署。
注意:PouchDb 也可以使用相同的协议同步到 CouchBase,但 Couchbase !== CouchDb。这是一个商业产品。
另一个很酷的技巧是 PouchDb 可以在 NodeJS 服务器中运行,以替代 CouchDb。我认为它(还没有)准备好用于生产,但对于单元测试非常方便。请参阅express-pouchdb。
迁移到 CouchDb 时需要考虑的一个问题是它具有更有限的访问控制模型。这部分是由于它的复制算法。这篇博客文章详细介绍了这一点(比真正的权威指南更好)。
在实践中,您可能希望将 WebSQL 用于您的 PouchDB 存储,因为它的性能要好得多。- 这是存储适配器的完整详细信息
多产的 PouchDb 社区总是从开源之门中涌现出一系列令人震惊的新酷“圣诞树”好东西。
PouchDb 的最佳特性之一是所有开源插件(37) 和 UI 框架适配器 (12)。
很老的问题,但问题仍然存在。我只使用了几天的 firebase,我自己找不到这个问题的令人满意的解决方案,所以我想我会分享我最终做了什么。
在应用程序启动时,我检查我是否在线navigator.onLine
。如果没有,我从本地存储中读取并从中恢复 firebase ref。
export const firebaseFromLocalStorage = (local, storeRef) => {
// assuming data is array
const localData = JSON.parse(localStorage.getItem(local)) || []
localData.map(obj => {
const key = obj['.key']
delete obj['.key']
storeRef
.child(key)
.set(obj)
})
}
然后照常进行。当应用程序上线时,它将与服务器同步其本地状态,就像它开始在线并暂时失去连接时一样。
当然,这意味着 localStorage 需要与您的 firebase ref 保持同步。我在每次获取操作时都这样做。
希望这可以帮助