Javascript 如何在firestore中以脱机方式读取文档并以脱机方式写入(联机和脱机)?

Javascript 如何在firestore中以脱机方式读取文档并以脱机方式写入(联机和脱机)?,javascript,firebase,react-native,google-cloud-firestore,Javascript,Firebase,React Native,Google Cloud Firestore,最近,我使用CloudFireStore和React Native创建了一个简单的聊天应用程序。他们的离线和在线同步是一个很好的特性 但是在加载(读取文档)时需要花费大量的时间。 虽然我为每个用户(10个用户)分页了10个文档,但加载消息的速度仍然非常慢,在缓慢的互联网连接中,加载消息最多需要10秒钟,这不是一个好的体验 在这里,当我启用脱机模式时,它加载消息的速度会快一点(大约3秒)。但有一个问题: 现在: 可以脱机加载邮件,并将邮件同时保存(脱机和联机) 或者有没有其他更好的方法可以更快地加

最近,我使用CloudFireStore和React Native创建了一个简单的聊天应用程序。他们的离线和在线同步是一个很好的特性


但是在加载(读取文档)时需要花费大量的时间。 虽然我为每个用户(10个用户)分页了10个文档,但加载消息的速度仍然非常慢,在缓慢的互联网连接中,加载消息最多需要10秒钟,这不是一个好的体验

在这里,当我启用脱机模式时,它加载消息的速度会快一点(大约3秒)。但有一个问题:

现在:

可以脱机加载邮件,并将邮件同时保存(脱机和联机)

或者有没有其他更好的方法可以更快地加载

当我在firebase中启用脱机功能时,它无法在服务器中保存邮件,或者我在保存邮件时禁用脱机功能,当我加载邮件时,它只加载脱机邮件

例如:

async function getMessagesOfAllUser(userlist){
    let outstate = false, data = {};
    if (userlist !== null)
        for (let i = userlist.length - 1; i >= 0; i--) {
            outstate = await this.getMessagesOfOneUsers(userlist[i].user);
            if (outstate !== false) data = { ...data, ...outstate };
            if (i === 0) {
                this.setState({ ...this.state, ...data });
            }
        }
}

function getMessagesOfOneUser(user) {
    return db.collection('users/'+user/+'/messages').orderBy("dt", "desc").limit(10).get().then(snap => {
        let l = snap.size;
        if (l > 0) {
            const ourMessage = this.state.me + user;
            this.lastVisible = { ...this.lastVisible, ...{ [user]: snap.docs[l - 1] } };
            for (let i = 0; i < l; i++) {
                if (this.outState[ourMessage] !== undefined)
                    this.outState[ourMessage] = [...this.outState[ourMessage], snap.docs[i].data()];
                else this.outState[ourMessage] = [snap.docs[i].data()];
                if (i === l - 1) return this.outState;
            }
        }
        return false;
    });
}
异步函数getMessagesOfAllUser(用户列表){
让outstate=false,data={};
if(userlist!==null)
for(设i=userlist.length-1;i>=0;i--){
outstate=wait this.getMessagesOfOneUsers(userlist[i].user);
如果(outstate!==false)数据={…数据,…outstate};
如果(i==0){
this.setState({…this.state,…data});
}
}
}
函数getMessagesOfOneUser(用户){
返回db.collection('users/'+user/+'/messages').orderBy(“dt”,“desc”).limit(10.get()。然后(snap=>{
设l=snap.size;
如果(l>0){
const ourMessage=this.state.me+用户;
this.lastVisible={…this.lastVisible,{[用户]:snap.docs[l-1]};
for(设i=0;i
当您使用
get()
(无参数)读取文档时,Firestore客户端将始终与服务器进行检查,以确保您获取最新数据

从本地缓存获取数据有两个选项:

  • 使用
    get({source:“cache”})
    (),它将从本地缓存返回文档。如果本地缓存中不存在文档,它将引发错误。在这种情况下,您仍然需要检查服务器

  • 使用
    onSnapshot()
    侦听器。当您附加此侦听器时,它会立即使用本地缓存中的值进行回调,就像
    get({source:“cache”})
    所做的那样。但它也会检查服务器是否有任何数据更新。如果有,它将检索更新的文档,更新本地缓存,并使用更新的值再次调用代码

  • 如果在用户界面中显示数据,通常建议使用
    onSnapshot()
    ,因为这意味着您的UI会对数据中的更改做出反应

    有关这方面的详细信息,请参阅视频系列中的。

    当您使用
    get()
    (无参数)读取文档时,Firestore客户端将始终与服务器进行检查,以确保您获取最新数据

    从本地缓存获取数据有两个选项:

  • 使用
    get({source:“cache”})
    (),它将从本地缓存返回文档。如果本地缓存中不存在文档,它将引发错误。在这种情况下,您仍然需要检查服务器

  • 使用
    onSnapshot()
    侦听器。当您附加此侦听器时,它会立即使用本地缓存中的值进行回调,就像
    get({source:“cache”})
    所做的那样。但它也会检查服务器是否有任何数据更新。如果有,它将检索更新的文档,更新本地缓存,并使用更新的值再次调用代码

  • 如果在用户界面中显示数据,通常建议使用
    onSnapshot()
    ,因为这意味着您的UI会对数据中的更改做出反应


    有关这方面的更多信息,请参阅视频系列中的。

    “但加载(阅读文档)会耗费大量时间。”这取决于您的阅读方式。
    get()
    总是尝试从服务器读取数据,但是
    onSnapshot
    实际上会立即触发本地数据,然后才检查服务器是否有新数据。如果您显示,将更容易帮助您。我可以使用onSnapshot读取多个文档,特别是用于读取和列出消息吗?可以在
    文档引用上调用onSnapshot
    onSnapshot
    (在这种情况下,它将为您提供一个
    文档快照
    )和
    查询上调用onSnapshot
    (在这种情况下,它将为您提供一个
    QuerySnapshot
    ,其中包含零个或多个
    DocumentSnapshot
    s)。如果你在这方面遇到困难,请分享。没有这一点,你将很难进一步帮助你。你好@FrankvanPuffelen,谢谢你的回复,你能看到问题中的示例吗,我已经编辑了我的问题。我的代码工作得很好,12个用户可以收到10条消息。但问题是,这需要很长的时间,即使在良好的互联网上,也需要大约7条消息秒,在糟糕的互联网中大约需要12秒。当我使用firebase调用
    disableNetwrok()
    函数时,大约需要3秒,这仍然不太好,但肯定比不使用
    disablenetwork()
    函数要好,“但加载(读取文档)时需要花费大量时间。”这取决于您的读取方式。
    get()
    将始终尝试从服务器读取数据,但是
    onSnapshot
    实际上会立即启动本地数据,然后才检查服务器是否有新数据。这将很容易