尝试将数据从我的 firebase 数据导出到 csv 文件给出未定义

Posted

技术标签:

【中文标题】尝试将数据从我的 firebase 数据导出到 csv 文件给出未定义【英文标题】:Trying to export data to csv file from my firebase data gives undefined 【发布时间】:2021-12-21 11:35:37 【问题描述】:

我有一个我想导出到 .csv 的 firebase firestore 中的数据列表

我做了所有需要的事情,但是当我添加要导出的值时,它们总是未定义。

我不是反应专家,我有点中级,但我认为这是因为我将数据设置在 useEffect Hook.

我的数据 useState 未定义,尽管它包含值并且我可以在我的表中看到它们,这导致 CSVLink 抛出错误。

我如何允许将我的数据传递到标头中?

这是我的代码:

  const [data, setData] = useState([]);
  const [id, setID] = useState("");
  const list = []
  const filteredList = []
  useEffect(() => 
    firebase.firestore().collection("Users").get().then((userSnapshot) => 

      userSnapshot.forEach((doc) => 
       
        const powerAccount,first_name,registerDate,email,company,country,phone = doc.data();
        setID(doc.data().usersID)
        list.push(
          usersID:doc.id,
          powerAccount:powerAccount,
          first_name:first_name,
          registerDate:registerDate,
          email:email,
          company:company,
          country:country,
          phone:phone,
        );
      );
      setData(list);
    );
  ,[]);


const headers = [
                  // here all the keys give undefined.
    label:'User',key:data.usersID,
    label:'Account',key:data.powerAccount,
    label:'Name',key:data.first_name,
    label:'RegistrationDate',key:data.registerDate,
    label:'Email',key:data.email,
    label:'Company',key:data.company,
    label:'Country',key:data.country,
    label:'Phone',key:data.phone,
  ];

 const csvReport = 
    filename:"userReport.csv",
    headers:headers,
    data: data // also my data useState is undefined, although it holds values and i can see them in my table
  

    return (
     <CSVLink  ...csvReport >
            Export
     </CSVLink>
    )

【问题讨论】:

从 firebase 获取数据是异步的,因此在您现在实施时数据将是未定义的。 【参考方案1】:

根据您的实现,从 firebase 获取数据是异步的,因此 csvData 变得未定义,因为它在状态更新后没有更新 尝试像这样更改您的代码,让我知道它是否可以正常工作

const [data, setData] = useState(
  filename: "userReport.csv",
  headers: [],
  data: [],
);
const [id, setID] = useState("");
const filteredList = [];
useEffect(() => 
  firebase
    .firestore()
    .collection("Users")
    .get()
    .then((userSnapshot) => 
      let list = [];
      userSnapshot.forEach((doc) => 
        const 
          powerAccount,
          first_name,
          registerDate,
          email,
          company,
          country,
          phone,
         = doc.data();
        setID(doc.data().usersID);
        list.push(
          usersID: doc.id,
          powerAccount: powerAccount,
          first_name: first_name,
          registerDate: registerDate,
          email: email,
          company: company,
          country: country,
          phone: phone,
        );
      );
      const headers = [
        // I'm not sure why you need this key
        // but if it's only for uniqueness
        // you can replace them by unique strings like
        //  label: "User", key: "user" ,
        //  label: "Account", key: "account" ,

         label: "User", key: data.usersID ,
         label: "Account", key: data.powerAccount ,
         label: "Name", key: data.first_name ,
         label: "RegistrationDate", key: data.registerDate ,
         label: "Email", key: data.email ,
         label: "Company", key: data.company ,
         label: "Country", key: data.country ,
         label: "Phone", key: data.phone ,
      ];

      const csvReport = 
        filename: "userReport.csv",
        headers: headers,
        data: list,
      ;
      setData(csvReport);
    );
, []);

return <CSVLink ...data>Export</CSVLink>;

【讨论】:

当我使用此代码时,我正在获取 data.map 不是一个函数。 我需要我的数据使用状态独立于 csv 报告。【参考方案2】:

您应该将所有状态协调/更新到 useStateuseEffect 挂钩,并避免依赖这些范围之外的任何字段更新。

然后您应该删除list 变量,将状态更新移动到您的效果挂钩并将所有用户数据合并到同一结构中:

const [data, setData] = useState([]);
useEffect(() => 
  firebase.firestore()
    .collection("Users")
    .get()
    .then((userSnapshot) => 
      const usersData = [];
      userSnapshot.forEach((doc) => 
        const  powerAccount, first_name, registerDate, email, company, country, phone, userID  = doc.data();
        const userData = 
          usersID: doc.id,
          powerAccount: powerAccount,
          first_name: first_name,
          registerDate: registerDate,
          email: email,
          company: company,
          country: country,
          phone: phone,
        ;
        const headers = [
          // here all the keys give undefined.
           label: 'User', key: userID ,
           label: 'Account', key: powerAccount ,
           label: 'Name', key: first_name ,
           label: 'RegistrationDate', key: registerDate ,
           label: 'Email', key: email ,
           label: 'Company', key: company ,
           label: 'Country', key: country ,
           label: 'Phone', key: phone ,
        ];
        const csvReport = 
          filename: "userReport.csv",
          headers: headers,
          data: userData
        
        usersData.push(csvReport);
      );
      setData(usersData);
    );
, []);

return (
  <CSVLink  ...data >
    Export
  </CSVLink>
)

您可能需要添加加载状态以反映正在加载的数据的 UI 效果。

【讨论】:

我在尝试读取此代码时遇到错误“数据应该是“字符串”、“数组数组”或“对象数组”我相信这是因为数据:userData 在csv报告 我需要我的 setData 与 csv 报告不同,在这里您正在推送 csvReport,这将导致当我尝试将我的用户提取到我的表中时没有为我提取任何用户【参考方案3】:

我认为有两件事会导致您需要了解问题。

    Asynchronous Function React Lifecycle

从 firebase 获取数据是异步的,当您将 csvReport 保存为常量变量并将其设置为 React 元素属性时,可能需要一段时间才能获得返回的数据。因此,当 firebase 仍在加载您的数据并且您的 react 组件已被渲染/安装时,您的 data 状态的值是 [],而不是 useState 语句中定义的默认值。根据您的代码,您的 csvReport 常量变量将不会从 firebase 接收新数据,除非您的应用程序被重新渲染(进入新的生命周期并重复)。比如切换到其他tab组件,不刷新浏览器就回到这个组件。

const csvReport = 
    filename:"userReport.csv",
    headers:headers, => [ label: "User", key: undefined , ...etc]; undefined bcs `data` is []
    data: data => the value is []
  

所以简单的解决方案是将数据保存为常量变量并直接从您的 useState 变量设置 React 元素属性。根据你的代码,我会做一些这样的改变。

...your previous code

const getHeaders = () => 
  // Do your data manipulation using `data` in useState
  // For example:
  const headers = data && data.map(item => return id: item.id)
  return headers


return (
  <CSVLink
    filename="userReport.csv"
    headers=getHeaders()
    data=data
  >
     Export
  </CSVLink>
)

希望这对您有所帮助,并在做出改变时玩得开心 :)

【讨论】:

仍然无法正常工作,因为 CSVLink 中未定义数据

以上是关于尝试将数据从我的 firebase 数据导出到 csv 文件给出未定义的主要内容,如果未能解决你的问题,请参考以下文章

我正在尝试将 firebase 实时数据库中的数据检索到我的 recyclerview 中,但数据显示为空

Firebase Rest Api 从我的模型类中读取数据返回 null [重复]

将 Google Firebase 导出到 Bigquery

MySql,如何将索引从我的开发数据库导出到我的生产数据库?

如何将所有事件数据从 Firebase 导出到 BigQuery?

使用 php 将数据库从我的实时服务器导出到我的本地主机?