如何将firebase存储下载URL保存到firestore集合?

Posted

技术标签:

【中文标题】如何将firebase存储下载URL保存到firestore集合?【英文标题】:How to save firebase storage downloadURL to firestore collection? 【发布时间】:2021-10-01 11:08:21 【问题描述】:

我无法将我的 firebase 存储映像保存到 firestore 集合变量中。它工作了一段时间,但后来停止工作。 image 变量返回 null。

p.s - 我使用的是 asia-south1 服务器

这是我的 ManageProducts 模板代码

<div>
      <h1>Add Items</h1>
      <div>
        <form>
          <input type="text" placeholder="name" required v-model="item.name" />
          <textarea
            required
            placeholder="description"
            v-model="item.description"
          ></textarea>
          <input
            type="text"
            required
            placeholder="price"
            v-model="item.price"
          />
          <div class="form-group">
            <input
              type="text"
              placeholder="Available/Unavailable"
              v-model.lazy="item.status"
              class="form-control"
            />
          </div>
          <div class="form-group">
            <input
              type="text"
              placeholder="Sewing Partner"
              v-model.lazy="item.sewingPartner"
              class="form-control"
            />
          </div>
          <input type="file" required @change="uploadImage" accept="image/*" />
          <button @click.prevent="AddNewItem">Add Item</button> |
          <button class="delete">
            Cancel
          </button>
        </form>
      </div>

这是管理产品的脚本。在这里,我可以添加除 Firebase 存储的图像 URL 之外的所有其他输入值。

  <script>
    import  dbItemAdd  from "../../main";
    import firebase from "firebase";
    import "firebase/firestore";
    import "firebase/storage";
    export default 
      name: "AddItems",
      components:  AdminPreviewItems ,
      data() 
        return 
          items: [],
          item: 
            name: null,
            description: null,
            image: null,
            price: null,
            status: null,
            sewingPartner: null,
          ,
        ;
      ,
      methods: 
        uploadImage(e) 
          let file = e.target.files[0];
          var storageRef = firebase.storage().ref("products/" + file.name);
          let uploadTask = storageRef.put(file);
          uploadTask.on(
            "state_changed",
            (snapshot) => 
              console.log(snapshot);
            ,
            (error) => 
              // Handle unsuccessful uploads
              console.log(error.message);
            ,
            () => 
              // Handle successful uploads on complete
              // For instance, get the download URL: https://firebasestorage.googleapis.com/...
              uploadTask.snapshot.ref.getDownloadURL().then((downloadURL) => 
                this.item.image = downloadURL;
                console.log("File available at", downloadURL);
              );
            
          );
        ,
    
        AddNewItem() 
          dbItemAdd
            .add(
              name: this.item.name,
              description: this.item.description,
              image: this.item.image,
              price: this.item.price,
              status: this.item.status,
              sewingPartner: this.item.sewingPartner,
            )
            .then(() => 
              location.reload();
              console.log("Adding data to Firestore");
            )
            .catch((error) => 
              console.error("Error adding document: ", error);
            );
        ,
      ,
    ;
    </script>

【问题讨论】:

我实际上看不到您是如何更新项目的,在调用 AddNewItem 之前,您应该有一些固有的逻辑来等待上传完成 - 这很可能是一个简单的竞争条件 嗨,我不太明白你的意思。您能否编写一些代码作为答案让我得到一个想法或某种东西? 这是 dbItemAdd 在 main.js 中的代码 - const dbItemAdd = firebase.firestore().collection("products");导出 dbItemAdd ; 【参考方案1】:

将文件上传到存储后,调用getDownloadURL() 将生成访问令牌

然后您将这个 URL 和访问令牌直接存储到 firestore 中

// Create reference to image
var mountainImagesRef = storageRef.child('images/mountains.jpg');
// Put image file to Storage
ref.put(file).then((snapshot) => 
// On complete, get the downloadURL
return mountainImagesRef.getDownloadURL())
.then((downloadURL) =>
// Add download URL to Firestore
firestore().doc("path/to/document/here").add(
              name: this.item.name,
              description: this.item.description,
              image: downloadURL,
              price: this.item.price,
              status: this.item.status,
              sewingPartner: this.item.sewingPartner,)
).catch(console.error);

【讨论】:

【参考方案2】:

您何时调用AddNewItem 函数?如果图片还没有上传或者downloadURL没有获取,点击提交按钮就会为空。

uploadTask.snapshot.ref.getDownloadURL().then((downloadURL) => 
  this.item.image = downloadURL;
  console.log("File available at", downloadURL);
  //function must be called after this
);

你可以禁用提交按钮是this.item.image为null(默认值)。

<button :disabled="!item.image" @click.prevent="AddNewItem">Add Item</button>

我没有看到 state_changed 观察者被使用。是否需要显示上传进度?如果是,请保持现有代码不变,否则我会将其重构为异步函数,如下所示:

async uploadImage(e) 
  let file = e.target.files[0];
  if (!file) alert("No file selected")
  var storageRef = firebase.storage().ref("products/" + file.name);
  let uploadTask = await storageRef.put(file);
  const url = await storageRef.getDownloadURL()
  this.item.image = url

您实际上是在文件更改时上传图像,而不是单击提交按钮,因此您可以在获取 downloadURL 后立即从 @change 事件本身添加 Firestore 文档。

【讨论】:

以上是关于如何将firebase存储下载URL保存到firestore集合?的主要内容,如果未能解决你的问题,请参考以下文章

如何在实时数据库firebase android中存储下载图像url

Firebase 存储上传图像不适用于亚马逊火灾(型号:Fire 7)

如何上传图片Url上传到Fire Storage并同时保存在fireStore中使用Java

如何将多个图像上传到 Firebase 存储并返回多个下载 URL

如何将 Firebase 上传图片的图片下载 URL 转换为 base64

将 Firebase 存储下载 URL 推送到 Firebase 云 Firestore