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

Firebase Cloud Firestore文档ID获取问题:card.id返回undefined怎么办?

Cloud Firestore中card.id返回undefined的解决方法

我在Cloud Firestore中存储任务卡片数据,运行以下代码时,card.id返回undefined:

<View style={styles.container}>
      {cards.map((card, index) => {
        console.log(card.id);
       ..
      ...
<View>

我原本以为Firebase会为每个文档提供唯一ID,请问我需要自行创建id属性,还是有Firebase原生的处理方法?

创建任务的代码

import { View, Text, Button, TextInput, StyleSheet } from "react-native";
import DateTimePicker from "@react-native-community/datetimepicker";

import React, { useState } from "react";
import { collection, addDoc } from "firebase/firestore";
import db from "../database/database";

export const CreateTaskScreen = ({ navigation }) => {
  const [state, SetState] = useState({
    title: "",
    description: "",
    date: new Date(),
    hour: new Date(),
  });

  const [showDatePicker, setShowDatePicker] = useState(false);
  const [showHourPicker, setShowHourPicker] = useState(false);

  const SetData = (key, value) => {
    SetState({
      ...state,
      [key]: value,
    });
  };

  async function HandlePress() {
    await addDoc(collection(db, "tasks"), {
      title: state.title,
      description: state.description,
      date: state.date,
      hour: state.hour,
    });
    navigation.navigate("TaskScreen");
  }

  const handleDatePress = () => {
    setShowDatePicker(true);
  };
  const handleHourPress = () => {
    setShowHourPicker(true);
  };
  const handleHourChange = (event, selectedHour) => {
    setShowHourPicker(false);
    if (selectedHour) {
      const currentHour = new Date(selectedHour);
      hour = currentHour.getHours();
      SetData("hour", hour);
    }
  };

  const handleDateChange = (event, selectedDate) => {
    setShowDatePicker(false);
    if (selectedDate) {
      const currentDate = new Date(selectedDate);
      SetData("date", currentDate);
    }
  };

  return (
    <View>
      <Text>Crear tarea</Text>
      <TextInput
        placeholder="Title"
        onChangeText={(value) => SetData("title", value)}
      />
      <TextInput
        placeholder="Description"
        multiline
        numberOfLines={4}
        onChangeText={(value) => SetData("description", value)}
      />
      <Button title="Select Date" onPress={handleDatePress} />
      {showDatePicker && (
        <DateTimePicker
          style={{ width: 200 }}
          value={state.date}
          mode="date"
          display="default"
          onChange={handleDateChange}
        />
      )}
      <Button title="Select Hour" onPress={handleHourPress} />
      {showHourPicker && (
        <DateTimePicker
          style={{ width: 200 }}
          value={state.hour}
          mode="time"
          display="default"
          is24Hour={true}
          onChange={handleHourChange}
        />
      )}
      <Button title="Save" onPress={HandlePress} />
    </View>
  );
};

获取数据的useEffect代码

useEffect(() => {
    const unsubscribe = onSnapshot(collection(db, "tasks"), (querySnapshot) => {
      const taskList = querySnapshot.docs.map((doc) => doc.data());
      setCards(taskList);
    });

    // Return the unsubscribe function to clean up the listener
    return () => unsubscribe();
  }, []);

问题原因及解决方法

问题出在获取数据的环节:你调用doc.data()只拿到了文档的内容字段,而文档的ID是Firestore文档的元数据,不会包含在data()返回的对象里。

不需要自行创建ID,Firebase有原生的处理方式,推荐两种方案:

方案1:获取数据时合并文档ID(推荐)

修改useEffect中的map逻辑,把文档ID和数据合并到同一个对象中:

useEffect(() => {
    const unsubscribe = onSnapshot(collection(db, "tasks"), (querySnapshot) => {
      const taskList = querySnapshot.docs.map((doc) => ({
        id: doc.id,
        ...doc.data()
      }));
      setCards(taskList);
    });

    return () => unsubscribe();
  }, []);

这样处理后,每个card对象就会包含id属性,直接访问card.id就能拿到文档的唯一ID。

方案2:创建文档时手动存储ID(不推荐)

如果一定要把ID存在文档内容里,可以在创建时先生成ID,再写入:

async function HandlePress() {
    // 先生成文档ID
    const taskRef = doc(collection(db, "tasks"));
    await setDoc(taskRef, {
      id: taskRef.id,
      title: state.title,
      description: state.description,
      date: state.date,
      hour: state.hour,
    });
    navigation.navigate("TaskScreen");
  }

但这种方式没必要,因为Firestore已经维护了文档ID作为元数据,重复存储会增加冗余。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 19:27:25