Firestore在React项目中重复上传

huangapple go评论61阅读模式
英文:

Firestore duplicating uploads in a react project

问题

我在将食谱上传到我的React应用程序中的Firestore时遇到了一个令人沮丧的问题。问题是数据在Firestore集合中重复,我似乎无法找出原因。

以下是代码示例:

首先是实际的 uploadRecipesToFirestore 代码片段:

export const uploadRecipesToFirestore = async (recipes) => {
    try {
      const recipesCollection = firebase.firestore().collection('recipes');
     
      const uploadPromises = recipes.map((recipe) => recipesCollection.add(recipe));
      await Promise.all(uploadPromises);
      console.log('Recipes uploaded to Firestore successfully!');
    } catch (error) {
      console.error('Error uploading recipes to Firestore:', error);
    }
  };

然后是 recipescontext--

import { createContext, useEffect, useState } from 'react';

import { fetchRecipesFromFirestore, uploadRecipesToFirestore } from '../utils/firebase-utils';
import PropTypes from 'prop-types';
import {recipes} from '../recipe-data';

export const RecipesContext = createContext([]);

export const RecipesProvider = ({ children }) => {
  const [isUploaded, setIsUploaded] = useState(false);
  const [fetchedRecipes, setFetchedRecipes] = useState([]);

  useEffect(() => {
    if (!isUploaded) {
      uploadRecipesToFirestore(recipes)
        .then(() => {
          console.log('Recipes uploaded to Firestore successfully!');
          setIsUploaded(true);
        })
        .catch((error) => {
          console.error('Error uploading recipes to Firestore:', error);
        });
    }
  }, [isUploaded]);

  useEffect(() => {
    const fetchRecipes = async () => {
      const recipes = await fetchRecipesFromFirestore();
      setFetchedRecipes(recipes);
    };

    fetchRecipes();
  }, []);

  return (
    <RecipesContext.Provider value={fetchedRecipes}>{children}</RecipesContext.Provider>
  );
};

RecipesProvider.propTypes = {
  children: PropTypes.node.isRequired
};

非常感谢您对可能导致此重复问题的任何见解或建议。如果您需要任何额外的信息,请告诉我。提前感谢您的帮助!

我想我应该提一下,当我安装firebase时,我遇到了一些漏洞,这是错误:

rotobufjs Prototype Pollution vulnerability - https://github.com/advisories/GHSA-h755-8qp9-cq85

修复方法是安装firebase的先前版本,但它被标记为破坏性变更。我是一名没有经验的新开发人员,不确定是否是正确的选择。我也不确定这是否可能导致问题,或者是否有关。我的计划是等待几天,直到可能有一个npm审计修复,不触发破坏性更改。这也是我第一次使用Vite而不是create-react-app,我不得不学习一些新的东西,create-react-app不要求的。

这是我尝试过的:

  1. 我有一个 RecipesProvider 组件,包装在我的应用程序中的 HomeRecipeShowcase 组件周围。在 RecipesProvider 中,我使用 uploadRecipesToFirestore 函数将食谱数据上传到Firestore。

  2. 我检查了对 uploadRecipesToFirestore 函数的重复调用,但在我的代码中只有一个出现。因此,我认为不是无意中多次调用的问题。

  3. 我还尝试将上传和获取逻辑分成两个单独的 useEffect 钩子,放在 RecipesProvider 组件中。我认为这可能会解决问题,但不幸的是,数据仍然重复。

  4. 我已经检查了Firestore配置、项目设置和Firebase项目设置,但一切似乎都井井有条。我没有看到任何明显的问题。

  5. 浏览器控制台没有显示任何错误,但有一个关于遇到重复键的警告。我认为这仅仅是因为数据本身重复导致的。

英文:

I'm running into a frustrating issue while uploading recipes to Firestore in my React application. The problem is that the data is being duplicated in the Firestore collection, and I can't seem to figure out why.

Here's how the code looks:

first the actual uploadRecipesToFirestore snippet:

export const uploadRecipesToFirestore = async (recipes) =&gt; {
    try {
      const recipesCollection = firebase.firestore().collection(&#39;recipes&#39;);
     
      const uploadPromises = recipes.map((recipe) =&gt; recipesCollection.add(recipe));
      await Promise.all(uploadPromises);
      console.log(&#39;Recipes uploaded to Firestore successfully!&#39;);
    } catch (error) {
      console.error(&#39;Error uploading recipes to Firestore:&#39;, error);
    }
  };

then the recipescontext--

import { createContext, useEffect, useState } from &#39;react&#39;;

import { fetchRecipesFromFirestore, uploadRecipesToFirestore } from &#39;../utils/firebase-utils&#39;;
import PropTypes from &#39;prop-types&#39;;
import {recipes} from &#39;../recipe-data&#39;

export const RecipesContext = createContext([]);

export const RecipesProvider = ({ children }) =&gt; {
  const [isUploaded, setIsUploaded] = useState(false);
  const [fetchedRecipes, setFetchedRecipes] = useState([]);

  useEffect(() =&gt; {
    if (!isUploaded) {
      uploadRecipesToFirestore(recipes)
        .then(() =&gt; {
          console.log(&#39;Recipes uploaded to Firestore successfully!&#39;);
          setIsUploaded(true);
        })
        .catch((error) =&gt; {
          console.error(&#39;Error uploading recipes to Firestore:&#39;, error);
        });
    }
  }, [isUploaded]);

  useEffect(() =&gt; {
    const fetchRecipes = async () =&gt; {
      const recipes = await fetchRecipesFromFirestore();
      setFetchedRecipes(recipes);
    };

    fetchRecipes();
  }, []);

  return (
    &lt;RecipesContext.Provider value={fetchedRecipes}&gt;{children}&lt;/RecipesContext.Provider&gt;
  );
};


RecipesProvider.propTypes = {
  children: PropTypes.node.isRequired
};

I'd really appreciate any insights or suggestions on what might be causing this duplication issue. If you need any additional information, please let me know. Thanks in advance for your help!

I guess I should mention I'm getting some vulnerabilities when installing firebase, this is the error:

rotobufjs Prototype Pollution vulnerability - https://github.com/advisories/GHSA-h755-8qp9-cq85

The fix is installing a previous version of firebase but it is labelled as a breaking change. I'm a new developer with no experience with this and I'm not sure if it's the right call. I am also not sure if that might be causing the issue or if it's at all related. My plan was to wait for a few days until maybe there was a npm audit fix that didn't trigger the breaking changes. This is also my first time using Vite instead of create-react-app, and I had to learn some new things that the create-react-app didn't demand.

This is what I've tried

  1. I have a RecipesProvider component that wraps around the Home and RecipeShowcase components in my app. Inside the RecipesProvider, I use the uploadRecipesToFirestore function to upload the recipe data to Firestore.

  2. I've checked for duplicate calls to the uploadRecipesToFirestore function, but there is only one occurrence in my code. So, I don't think unintentional multiple calls are the issue.

  3. I also tried separating the uploading and fetching logic into two separate useEffect hooks within the RecipesProvider component. I thought this might solve the problem, but unfortunately, the data is still being duplicated.

  4. I've reviewed the Firestore configuration, project settings, and Firebase project setup, but everything seems to be in order. I don't see any obvious issues there.

  5. The browser console doesn't show any errors, but there is a warning about encountering duplicate keys. I believe this is only happening because the data itself is being duplicated.

答案1

得分: 1

这可能是两个 useEffect 钩子同时运行引起的。为了防止重复,我们可以修改 useEffect 如下:

useEffect(() => {
  uploadRecipesToFirestore(recipes)
    .then(() => {
      console.log('Recipes uploaded to Firestore successfully!');
      setIsUploaded(true);
    })
    .catch((error) => {
      console.error('Error uploading recipes to Firestore:', error);
    });
}, []);

另外,您提到了Firebase的安全问题。为了解决这个问题,在对 useEffect 进行任何更改之前,将Firebase更新到一个没有任何破坏性变化的安全版本。

英文:

This might be caused by two useEffect hooks running at the same time. To prevent duplicates, we can modify the useEffect like this:

useEffect(() =&gt; {
  uploadRecipesToFirestore(recipes)
    .then(() =&gt; {
      console.log(&#39;Recipes uploaded to Firestore successfully!&#39;);
      setIsUploaded(true);
    })
    .catch((error) =&gt; {
      console.error(&#39;Error uploading recipes to Firestore:&#39;, error);
    });
}, []);

Additionally, you mentioned a security issue with Firebase. To fix that, update Firebase to a secure version without any breaking changes before making changes to the useEffect.

huangapple
  • 本文由 发表于 2023年7月13日 00:58:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/76672904.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定