我是Firebase的新手,并将其与React Native一起使用。我正在尝试使用Firebase中的数据填充ListView。我看到我现在可以在Firebase中使用Promise,但是,似乎我不能将它们与.on()
一起使用,而只能与.once
一起使用。因为我需要听取更改,所以我需要使用.on()
。
现在,当我想确保在从Firebase检索数据之后(并且仅在之后)设置状态时,我现在面临挑战。我的代码如下:
listen() {
var self = this
var currentUserID = firebase.auth().currentUser.uid
var postList = firebase.database().ref('/users/'+currentUserID+'/postKeys')
postList.on('value', function(snapshot) {
var posts = []
snapshot.forEach((child)=> {
var postID = child.val().postID
var postRef = firebase.database().ref('posts/'+postID)
postRef.orderByChild('sortedDateInMilliseconds').on('value', function(postSnap) {
posts.push(postSnap.val())
})
})
self.setState({
postCount:posts.length,
dataSource:self.state.dataSource.cloneWithRows(posts)
})
})
}
结果是我最初得到一个空视图,因为在查询填充posts数组之前调用了render()
。有谁知道如何确保在查询填充数组后调用self.setState({})
?
非常感谢你的帮助。
答案 0 :(得分:1)
我不完全确定用空数组调用你的意思。我可以想象的唯一原因是,如果您最初在该位置尚无数据时被调用。如果这是原因,您可以使用snapshot.exists()
检测到它:
listen() {
var self = this
var currentUserID = firebase.auth().currentUser.uid
var postList = firebase.database().ref('/users/'+currentUserID+'/postKeys')
postList.on('value', function(snapshot) {
if (snapshot.exists()) {
var posts = []
snapshot.forEach((child)=> {
var postID = child.val().postID
var postRef = firebase.database().ref('posts/'+postID)
postRef.orderByChild('sortedDateInMilliseconds').on('value', function(postSnap) {
posts.push(postSnap.val())
})
})
self.setState({
postCount:posts.length,
dataSource:self.state.dataSource.cloneWithRows(posts)
})
}
})
}
如果这不能解决问题,你可以设置一个再现它的jsbin吗?
答案 1 :(得分:-2)
您可以将setTimeout
功能用作
setTimeOut(try,3000);
function try(){
self.setState({
postCount:posts.length,
dataSource:self.state.dataSource.cloneWithRows(posts)
});
}
如果不将3000更改为5000
,将在查询后调用self.setState({})