我正在考虑使用firebase来编写使用PhoneGap和HTML5应用程序缓存的移动应用程序。
假设每个用户都有一个TODO项目列表。如果在手机离线时启动应用程序,它是否能够从上一个会话加载数据并在建立连接时同步?如果是这样,我想知道这是如何实现的,因为我在firebase.js中找不到对localStorage的引用。
答案 0 :(得分:21)
简短的回答是:还没有。
一旦应用程序连接到Firebase,客户端将在本地缓存数据,并且即使在网络连接丢失后也能够访问存在未完成“on”回调的数据。但是,此数据不会持久保存到磁盘,“离线模式”仅在应用程序仍在运行时才有效。
将来会有完整的离线支持。
编辑2016:现在可以为原生iOS和Android应用提供完全离线支持:https://www.firebase.com/blog/2015-05-29-announcing-mobile-offline-support.html
答案 1 :(得分:9)
解决JS应用程序此问题的Firebase的替代方案是CouchDb(服务器)< => PouchDb(JS客户端)。如果您已经实现了一个漂亮干净的客户端服务层,那么移植到PouchDb应该是相当直接的,因为它们都是NoSQL / JSON数据库。 CouchDb还支持索引的map / reduce视图。
PouchDb是一个实现完全脱机 CouchDb客户端的Javascript API。它可以自动检测并使用本地存储, IndexDb 或 WebSQL ,以在线或离线时永久保留本地数据。 PouchDb API可用于访问本地或远程数据库(只需更改URL),并在两者之间连接完整同步或过滤同步。有许多有用的PouchDb插件,代码示例和一个小的包装器库来支持AngularJS的Q promises 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)=>进行扩展。单个服务器=>多主(复制)=> Big Couch Clustered / Geo Clustered。与MongoDb不同,CouchDb安全地支持单服务器部署。
注意:PouchDb也可以使用相同的协议同步到CouchBase但Couchbase!== CouchDb。它是一种商业产品。
另一个很酷的技巧是PouchDb可以在NodeJS服务器内运行,作为CouchDb的替代品。我认为它还没有准备好用于生产,但对于单元测试非常方便。请参阅express-pouchdb。
迁移到CouchDb时,您需要考虑的一个问题是它具有更有限的访问控制模型。这部分是由于它的复制算法。这篇博文详细介绍了这一点(优于真正的权威指南)。
在实践中,您可能希望将WebSQL用于PouchDB存储,因为它的性能要好得多。 - 这是full details on the storage adapters
有一系列令人震惊的新酷"圣诞树"好东西总是从多产的PouchDb社区中淘汰开源门。
PouchDb的最佳功能之一是所有开源plugins(37)和UI框架适配器(12)。
答案 2 :(得分:0)
很老的问题,但问题仍然存在。 我一直在使用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保持同步。我在每次获取操作时执行此操作。
希望这有帮助