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

React+Redux应用:Firebase图片URL写入数据库丢失问题求助

Troubleshooting Your React+Redux Recipe App's Image URL Update Issue

Hey there! Let's break down what's going wrong with your React+Redux recipe app and fix it step by step. The core problem here is that even though you're using await for your image uploads, the timing or promise handling is off—so your Firebase database and Redux store aren't getting the updated imageUrls even though the logger shows them correctly.

Common Culprits & Fixes

1. Your uploadImages Function Isn't Properly Returning Resolved URLs

First, let's make sure your image upload function is actually waiting for all uploads to finish and returning the full array of URLs. A common mistake is using forEach (which doesn't play nice with async/await) instead of map + Promise.all.

Here's a corrected version of uploadImages:

const uploadImages = async (imagesToAdd, recipeKey) => {
  if (!imagesToAdd || imagesToAdd.length === 0) return [];

  // Map each image to an upload promise, then wait for all to complete
  const uploadPromises = imagesToAdd.map(async (image) => {
    const storageRef = firebase.storage().ref(`recipes/${recipeKey}/${image.name}`);
    await storageRef.put(image); // Wait for upload to finish
    return storageRef.getDownloadURL(); // Return the URL promise
  });

  // Wait for ALL uploads to resolve before returning the URL array
  return Promise.all(uploadPromises);
};

2. Your startAddRecipe Action Isn't Waiting for Updates to Complete

Next, let's fix the action to ensure it waits for the image uploads, updates the Firebase database, and then dispatches the correct data to Redux. You need to await the database update and make sure you're passing the full imageUrls array when dispatching.

Here's the revised thunk action:

export const startAddRecipe = (recipeData) => {
  return async (dispatch) => {
    const { imagesToAdd, ...restRecipeData } = recipeData;

    // Step 1: Create initial recipe in Firebase and get the key
    const recipesRef = firebase.database().ref('recipes');
    const newRecipeRef = recipesRef.push(restRecipeData);
    const recipeKey = newRecipeRef.key;

    try {
      let imageUrls = [];
      // Step 2: Upload images (wait for completion!)
      if (imagesToAdd?.length > 0) {
        imageUrls = await uploadImages(imagesToAdd, recipeKey);
        console.log('Fetched Image URLs:', imageUrls); // This should now be a full array
      }

      // Step 3: Update the Firebase recipe with imageUrls (await this!)
      await newRecipeRef.update({ imageUrls });

      // Step 4: Dispatch the FULL recipe data to Redux
      dispatch(addRecipe({
        id: recipeKey,
        ...restRecipeData,
        imageUrls
      }));
    } catch (err) {
      console.error('Failed to add recipe:', err);
      // Optional: Clean up partial data (e.g., delete uploaded images/recipe entry)
    }
  };
};

3. Double-Check Your Redux Reducer

Make sure your reducer is correctly handling the ADD_RECIPE action and returning a new state array with the updated recipe. It's easy to accidentally mutate state or forget to include imageUrls:

const recipesReducer = (state = [], action) => {
  switch (action.type) {
    case 'ADD_RECIPE':
      // Return a NEW array with the new recipe (never mutate state!)
      return [...state, { ...action.recipe }];
    // Handle other actions here...
    default:
      return state;
  }
};

4. Verify Firebase Database Rules

Don't forget to check your Firebase Realtime Database rules—if you don't have write permissions for updating existing entries, the update will fail silently. A temporary test rule (not for production!) would look like:

{
  "rules": {
    ".read": true,
    ".write": true
  }
}

Why This Works

The key fixes here are:

  • Using Promise.all to wait for all image uploads to finish before proceeding
  • await-ing the Firebase database update to ensure it completes before dispatching to Redux
  • Making sure your reducer returns a new state object with the full recipe data (including imageUrls)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 15:27:51