React Native Firebase Firestore数据获取空白,文档展示异常求助
问题描述
我在Firestore数据库中创建了3个文档,每个文档包含不同的数据。但当我为不同文档ID添加不同数据后,页面出现空白区域,这些空白会自动出现在我之前创建的其他文档ID对应的位置。我希望文档1展示在第一个页面,文档2展示在第二个页面,即每个文档的数据仅在对应页面显示。



当前代码
第一个页面(Testing组件)
import React, { useState, useEffect } from 'react'; import {View, Button, Text, FlatList, StyleSheet, Pressable, TouchableOpacity} from 'react-native' import {firebase} from '../config'; const Testing = ({ navigation }) =>{ const [users, setUsers] = useState([]); const todoRef = firebase.firestore().collection('testing'); useEffect(() => { todoRef.onSnapshot( querySnapshot => { const users = [] querySnapshot.forEach((doc) => { const { One, Two, Three } = doc.data() users.push({ id: doc.id, One, Two, Three }) }) setUsers(users) } ) }, []) return ( <View style={{ flex:1,}}> <FlatList style={{height: '100%'}} data={users} numColumns={1} renderItem={({item}) => ( <Pressable > <View style={styles.viewOne}> <View> <Text style={[styles.card, styles.title]}>{item.One}</Text> <Text style={styles.text}>{item.Two}</Text> <Text style={styles.text}>{item.Three}</Text> </View> </View> </Pressable> )} /> </View> );} export default Testing;
第二个页面(TestingDocs组件)
import React, { useState, useEffect } from 'react'; import {View, Button, Text, FlatList, StyleSheet, Pressable, TouchableOpacity} from 'react-native' import {firebase} from '../config'; const TestingDocs = ({ navigation }) =>{ const [users, setUsers] = useState([]); const todoRef = firebase.firestore().collection('testing'); useEffect(() => { todoRef.onSnapshot( querySnapshot => { const users = [] querySnapshot.forEach((doc) => { const { DocsOne, DocsTwo, DocsThree, } = doc.data() users.push({ id: doc.id, DocsOne, DocsTwo, DocsThree, }) }) setUsers(users) } ) }, []) return ( <View style={{ flex:1,}}> <FlatList style={{height: '100%'}} data={users} numColumns={1} renderItem={({item}) => ( <Pressable > <View style={styles.viewOne}> <View> <Text style={[styles.card, styles.title]}>{item.DocsOne}</Text> <Text style={styles.text}>{item.DocsTwo}</Text> <Text style={styles.text}>{item.DocsThree}</Text> </View> </View> </Pressable> )} /> </View> );} export default TestingDocs;
解决方案
问题根源是当前代码会拉取testing集合下的所有文档,但每个页面只需要展示特定文档。只需在Firestore查询时指定对应文档ID,而非获取整个集合的文档即可解决。
修改后的第一个页面(仅加载指定文档)
import React, { useState, useEffect } from 'react'; import {View, Text, StyleSheet, Pressable} from 'react-native' import {firebase} from '../config'; const Testing = ({ navigation }) =>{ const [user, setUser] = useState(null); // 替换为你要展示的第一个文档的ID const targetDocId = "文档1的ID"; const todoRef = firebase.firestore().collection('testing').doc(targetDocId); useEffect(() => { const unsubscribe = todoRef.onSnapshot( docSnapshot => { if (docSnapshot.exists) { const { One, Two, Three } = docSnapshot.data(); setUser({ id: docSnapshot.id, One, Two, Three }); } else { setUser(null); } } ); // 组件卸载时取消监听,避免内存泄漏 return unsubscribe; }, []) if (!user) { return <View style={{flex:1, justifyContent:'center', alignItems:'center'}}><Text>加载中...</Text></View>; } return ( <View style={{ flex:1,}}> <Pressable> <View style={styles.viewOne}> <View> <Text style={[styles.card, styles.title]}>{user.One}</Text> <Text style={styles.text}>{user.Two}</Text> <Text style={styles.text}>{user.Three}</Text> </View> </View> </Pressable> </View> );} export default Testing;
修改后的第二个页面(仅加载指定文档)
import React, { useState, useEffect } from 'react'; import {View, Text, StyleSheet, Pressable} from 'react-native' import {firebase} from '../config'; const TestingDocs = ({ navigation }) =>{ const [user, setUser] = useState(null); // 替换为你要展示的第二个文档的ID const targetDocId = "文档2的ID"; const todoRef = firebase.firestore().collection('testing').doc(targetDocId); useEffect(() => { const unsubscribe = todoRef.onSnapshot( docSnapshot => { if (docSnapshot.exists) { const { DocsOne, DocsTwo, DocsThree } = docSnapshot.data(); setUser({ id: docSnapshot.id, DocsOne, DocsTwo, DocsThree }); } else { setUser(null); } } ); // 组件卸载时取消监听,避免内存泄漏 return unsubscribe; }, []) if (!user) { return <View style={{flex:1, justifyContent:'center', alignItems:'center'}}><Text>加载中...</Text></View>; } return ( <View style={{ flex:1,}}> <Pressable> <View style={styles.viewOne}> <View> <Text style={[styles.card, styles.title]}>{user.DocsOne}</Text> <Text style={styles.text}>{user.DocsTwo}</Text> <Text style={styles.text}>{user.DocsThree}</Text> </View> </View> </Pressable> </View> );} export default TestingDocs;
关键修改点
- 改用
collection().doc(文档ID).onSnapshot()监听单个指定文档,而非获取整个集合的文档 - 无需再使用
FlatList,直接渲染单个数据,避免无关文档导致的空白项 - 添加了文档不存在时的加载状态提示
- 组件卸载时取消Firestore监听,防止内存泄漏
内容的提问来源于stack exchange,提问作者Rahul Aadam
相关产品推荐
相关产品推荐

