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

Firebase 9 + React Native 获取Cloud Firestore文档返回空数组问题

解决Firebase Firestore获取文档返回空数组的问题

使用Firebase 9.9.4版本,尝试从Firestore的values集合获取文档时始终得到空数组,以下是问题分析和修复方案:


问题分析

1. 初始实现的异步逻辑错误

在useLayoutEffect中,onSnapshot的回调是异步执行的,你在调用getValues()后立刻console.log(values),此时回调还未触发,因此values为空数组。同时没有用React状态存储数据,即使后续获取到数据,组件也不会重新渲染。

2. 自定义Hook的使用疏漏

你的useFireStore Hook逻辑本身正确,但组件中存在两个问题:

  • 未将获取到的docs关联到轮播组件的数据源carouselItems
  • 监听docs的useEffect依赖为空,无法响应数据变化

修复方案

方案1:修正初始实现的异步逻辑

useLayoutEffect(() => {
  const q = query(collection(db, "values"));
  // 订阅数据变化
  const unsubscribe = onSnapshot(q, (querySnapshot) => {
    // 遍历快照提取文档数据
    const fetchedValues = querySnapshot.docs.map(doc => doc.data());
    console.log(fetchedValues); // 此处可获取正确数据
    // 用状态存储数据,触发组件更新
    setValues(fetchedValues);
  });
  // 组件卸载时取消订阅,避免内存泄漏
  return () => unsubscribe();
}, [])

方案2:正确使用自定义Hook

// 完善自定义Hook(补充返回值)
export const useFireStore = (mycollection : string) => {
  const [docs, setDocs] = useState<any>([]);

  useEffect(() => {
    const unsub = onSnapshot(collection(db, mycollection), (querySnapshot) => {
      const documents = querySnapshot.docs.map((doc) => ({
        ...doc.data(),
        id: doc.id // 建议携带文档ID,方便后续操作
      }));
      setDocs(documents);
    });
    return () => unsub();
  }, [mycollection])
  
  return docs; // 必须返回获取到的文档数组
}

// 组件中正确使用Hook
const ProfilesScreen: React.FC<Props> = ({ navigation, route}) => {
  const carouselRef = useRef()
  const [activeIndex, setActiveIndex] = useState<number>()
  const [carouselItems, setCarouselItems] = useState<any[]>([]);
  const windowHeight = useWindowDimensions().height;
  const windowWidth = useWindowDimensions().width;

  navigation.setOptions({
    headerShown: false,
  }) 

  // 调用自定义Hook获取数据
  const docs = useFireStore('values')
 
  // 监听docs变化,更新轮播数据源
  useEffect(() => {
    if(docs.length > 0) {
      console.log("docs", docs);
      setCarouselItems(docs);
    }
  }, [docs]);

  return(
    <SafeAreaView style={{flex: 1, backgroundColor:'white', paddingTop: 50, }}>
      <View style={{ flex: 1, flexDirection:'row', justifyContent: 'center', paddingTop:20}}>
            <Carousel
              layout={"default"}
              ref={carouselRef}
              data={carouselItems} // 使用更新后的数据源
              sliderWidth={windowWidth}
              itemHeight={windowHeight}
              itemWidth={windowWidth}
              renderItem={ProfileScreenItem}
              onSnapToItem = {(index : number) => setActiveIndex(index)} 
            />
         </View>
        <SideBar carouselRef={carouselRef}/>
      </SafeAreaView>
    )
}

额外检查项

  • Firestore安全规则:确认规则允许读取操作,开发阶段可临时设置为:
    rules_version = '2';
    service cloud.firestore {
      match /databases/{database}/documents {
        match /{document=**} {
          allow read, write: if request.auth != null; // 测试时可改为if true;
        }
      }
    }
    
    正式环境需设置严格权限。
  • 集合名称与文档存在性:确认Firestore控制台中values集合名称(大小写敏感)正确,且集合内存在文档。

内容的提问来源于stack exchange,提问作者RandomDeveloper

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 04:10:34