使用 uploadBytes 调用 firebase 后无法设置 ImageURL

问题描述 投票:0回答:2

为什么

imageURL
总是
null
uploadBytes
肯定会返回一个
imageURL
。我在调用
imageURL
之前设置了
addDoc
。但我可以从图像 URL 中控制它。它与 promises 或 async/await 有关吗?

const uploadPhoto = (upload) => {
    if (upload === undefined) {
      return;
    }
    const imageRef = ref(storage, `images/inventory/${upload[0].uid}`);
    uploadBytes(imageRef, upload[0].originFileObj)
      .then((snapshot) => {
        return getDownloadURL(snapshot.ref);
      })
      .then((downloadURL) => {
        setImageURL(downloadURL);
        console.log("Download URL", downloadURL);
      });
  };
  delete addInventoryDetailsFormData.upload;
  Promise.all([
    uploadPhoto(upload),
    addDoc(inventoryCollectionRef, {
      ...inventoryFormData,
      ...addInventoryDetailsFormData,
      createdTime: Date.now(),
      region: User.region ? User.region : "Global",
      createdBy: User.username,
      roleId: User.roleId,
      imageURL: imageURL,
    }),
  ])
    .then(() => navigate("/app/news-manage/draft"))
    .then(() => message.success("Inventory successfully added", 5));
} catch (error) {
  console.log(error);
}

javascript reactjs google-cloud-firestore firebase-storage
2个回答
0
投票

您需要确保:

  1. 在您请求下载网址之前上传已完成
  2. 在尝试写入数据库之前,请确保已设置下载网址

您的代码执行#1,但不执行#2。使用

Promise.all()
在这里没有帮助,因为
setImageURL
本身也是异步的 - 更糟糕的是:一个不返回你可以等待的承诺。

与其通过 React 的状态(用于您要在其 UI 中呈现的数据)传递下载 URL,不如考虑简单地使用局部变量和返回值。

像这样的东西:

const uploadPhoto = (upload) => {
  if (upload === undefined) {
    return;
  }
  const imageRef = ref(storage, `images/inventory/${upload[0].uid}`);
  return uploadBytes(imageRef, upload[0].originFileObj) // 👈
    .then((snapshot) => {
      return getDownloadURL(snapshot.ref);
    })
    .then((downloadURL) => {
      console.log("Download URL", downloadURL);
      return downloadURL; // 👈
    });
};

uploadPhoto(upload).then((downloadURL) => { // 👈
  addDoc(inventoryCollectionRef, {
    ...inventoryFormData,
    ...addInventoryDetailsFormData,
    createdTime: Date.now(),
    region: User.region ? User.region : "Global",
    createdBy: User.username,
    roleId: User.roleId,
    imageURL: downloadURL, // 👈
  }),
])

0
投票

我设法通过稍微改变结构来做到这一点。这是解决方案,感谢 Frank 对这个问题的解释

 const saveInventory = () => {
try {
  const inventoryFormData = inventoryForm.getFieldValue();
  const addInventoryDetailsFormData = addInventoryDetailsForm.current.getFieldValue();
  const upload = addInventoryDetailsFormData.upload;
  console.log(upload);
  if (upload === undefined) {
    delete addInventoryDetailsFormData.upload;
    addDoc(inventoryCollectionRef, {
      ...inventoryFormData,
      ...addInventoryDetailsFormData,
      createdTime: Date.now(),
      region: User.region ? User.region : "Global",
      createdBy: User.username,
      roleId: User.roleId,
      imageURL: null,
    })
      .then(() => navigate("/app/news-manage/draft"))
      .then(() => message.success("Inventory successfully added", 5));
  } else {
    const imageRef = ref(storage, `images/inventory/${upload[0].uid}`);
    uploadBytes(imageRef, upload[0].originFileObj)
      .then((snapshot) => {
        return getDownloadURL(snapshot.ref);
      })
      .then((downloadURL) => {
        delete addInventoryDetailsFormData.upload;
        addDoc(inventoryCollectionRef, {
          ...inventoryFormData,
          ...addInventoryDetailsFormData,
          createdTime: Date.now(),
          region: User.region ? User.region : "Global",
          createdBy: User.username,
          roleId: User.roleId,
          imageURL: downloadURL,
        })
          .then(() => navigate("/app/news-manage/draft"))
          .then(() => message.success("Inventory successfully added", 5));
      });
  }
} catch (error) {
  console.log(error);
}
};
© www.soinside.com 2019 - 2024. All rights reserved.