我正在使用Firebase构建一个React Native应用程序。我在一个组件中使用以下方法(除其他方法外)从Firebase获取数据:
loadMessagesFromFirebase(chatId){
let messageList = [];
let data = {};
let message = {};
const dataRef = firebase.database().ref('chats').child(chatId);
dataRef.on('value', datasnap=>{
data = datasnap.val()
})
for (var sayer in data){
for (var m in data[sayer]){
message = {sayer: sayer, text: m.text, time: new Date(m.created)};
messageList.push(message);
}
}
messageList.sort((a,b) => (a.time > b.time) ? 1: -1);
this.setState({messageList: messageList});
}
问题在于,数据偶尔会作为空字典(对象{})加载,因此消息列表将为空。我认为发生这种情况是因为我没有给Firebase足够的加载时间。如何使此函数异步,以便可以向组件添加“正在加载”状态,直到加载完成才显示消息信息?
async componentDidMount(){
firebase.initializeApp(FirebaseConfig);
this.loadMessagesFromFirebase(this.state.chatId);
//once the messages are done loading
this.setState({{loading: false}})
}
此外,是否有一种方法可以确保,如果数据作为空字典返回,是因为Firebase已完成加载,而不是因为该聊天ID没有数据?
尽管OP似乎已经找到了答案,但回答了这个问题,因为他没有解释基本概念。
Firebase SDK使用异步编程和观察者模式来提供实时更新。
在React Native世界上获取异步Firebase数据的正确方法如下。
在应用程序启动期间,仅初始化一次firebase sdk。用React术语,这可以在顶级App组件的构造函数中完成。有关步骤,请参见firebase文档。https://firebase.google.com/docs/database/web/start
在组件构造函数或componentDidMount内部,设置对firebase函数的调用以加载数据 componentDidMount(){ this.loadMessagesFromFirebase(this.state.chatId); }
在加载消息功能中,异步调用Firebase Realtor数据库。在此处了解更多信息https://firebase.google.com/docs/database/web/read-and-write
这里要记住的主要事情是,必须在写入异步回调后触发所有在数据可用后必须运行的代码。修改问题中的示例代码
loadMessagesFromFirebase(chatId){
let data = {};
let output = {};
const dataRef = firebase.database().ref('chats').child(chatId);
dataRef.once('value', datasnap=>{
data = datasnap.val();
// Do something really smart with the data and assign it to output
......
output = data;
// set updates to the state
this.setState({output: output});
})
}
注意使用once
代替代替on
功能。这样做的原因是,获取观察者的订阅on
可能导致每次数据更改时触发回调。如果组件被设计为仅获取一次数据,则可能导致不良后果。
进一步阅读https://firebase.google.com/docs/database/web/read-and-write
如果希望每次发生数据更改时都更新组件,然后使用该on
功能设置对该数据的预订。但是,在这种情况下,取消内部的订阅很重要componentWillUnmount
https://firebase.google.com/docs/reference/js/firebase.database.Reference#off
可以总结如下
`
// inside componentDidMount
this.onValueChange = ref.on('value', function(dataSnapshot) { ... });
// Sometime later.... Inside componentWillUnmount
ref.off('value', this.onValueChange);`
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句