You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native Firebase Firestore数据获取空白,文档展示异常求助

问题描述

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

Firestore文档展示问题1
Firestore文档展示问题2
Firestore文档展示问题3

当前代码

第一个页面(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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 02:57:52