【问题标题】:Problem displaying uploaded image from firebase when refreshing page刷新页面时显示从 Firebase 上传的图像时出现问题
【发布时间】:2020-04-18 14:25:57
【问题描述】:

大家好,新年快乐!也许有人知道为什么会发生这种情况?数据库中有图像的链接,所有内容也都加载到存储中。并且添加图像后,一切都很好,直到页面被刷新。请帮助某人。我在 Google 中没有找到问题的答案。

import Vue from 'vue'
import Vuex from 'vuex'
import user from './user'
import cart from './cart'
import loading from './loading'
import * as fb from 'firebase/app'

Vue.use(Vuex)
class Product {
  constructor (title, price, description, ownerId, imageSrc = '', id = null) {
    this.title = title
    this.price = price
    this.description = description
    this.ownerId = ownerId
    this.imageSrc = imageSrc
    this.id = id
  }
}

export default function (/* { ssrContext } */) {
  const Store = new Vuex.Store({
    state: {
      amount: 1,
      products: [
      ]
    },
    getters: {
      addById (state) {
        return addId => {
          return state.products.find(product => product.id === addId)
        }
      },
      products (state) {
        return state.products
      }
    },
    actions: {
      async CREATE_PRODUCT ({ commit, getters }, payload) {
        commit('SET_LOADING', true)
        const image = payload.image

        try {
          const newProduct = new Product(payload.title, payload.price, payload.description, getters.user.id, '')
          const product = await fb.database().ref('products').push(newProduct)
          const imageExt = image.name.slice(image.name.lastIndexOf('.'))
          const fileData = await fb.storage().ref(`products/${product.key}.${imageExt}`).put(image)
          // const imageSrc = await fb.storage().ref().StorageReference(fileData.ref.fullPath).getDownloadUrl()
          const imageSrc = await fileData.ref.getStorage().getDownloadURL()
          await fb.database().ref('products').child(product.key).update({ imageSrc })
          commit('SET_LOADING', false)
          commit('CREATE_PRODUCT', {
            ...newProduct,
            id: product.key,
            imageSrc
          })
        } catch (error) {
          commit('SET_LOADING', false)
          throw error
        }
      },
      async fetchProducts ({ commit }) {
        commit('SET_LOADING', true)
        const resultProducts = []
        try {
          const fbVal = await fb.database().ref('products').once('value')
          const products = fbVal.val()
          Object.keys(products).forEach(key => {
            const product = products[key]
            resultProducts.push(
              new Product(product.title, product.price, product.description, product.imageSrc, product.ownerId, key)
            )
          })
          commit('LOAD_PRODUCTS', resultProducts)
          commit('SET_LOADING', false)
        } catch (error) {
          commit('SET_LOADING', false)
          throw error
        }
      }
    },
    mutations: {
      CREATE_PRODUCT (state, payload) {
        state.products.push(payload)
      },
      LOAD_PRODUCTS (state, payload) {
        state.products = payload
      }
    },
    modules: {
      user,
      loading,
      cart
    },

    strict: process.env.DEV
  })

  return Store
}

【问题讨论】:

  • 页面刷新时出现什么问题?
  • 图像消失

标签: firebase vue.js vuex


【解决方案1】:

在您的 fetchProducts() 函数中,当您初始化要添加到商店的每个产品时,您的参数乱序,其中 imageSrcownerId 的方向错误。

new Product(product.title, product.price, product.description, product.imageSrc, product.ownerId, key)

需要改成

new Product(product.title, product.price, product.description, product.ownerId, product.imageSrc, key)

其他改进

CREATE_PRODUCT,考虑同时上传产品数据和图片,而不是一个接一个。

async CREATE_PRODUCT ({ commit, getters }, payload) {
  commit('SET_LOADING', true)
  const image = payload.image

  try {
    const newProduct = new Product(payload.title, payload.price, payload.description, getters.user.id, '')
    const imageExt = image.name.slice(image.name.lastIndexOf('.'))
    const productRef = fb.database().ref('products').push(); // generates push ID without uploading data

    const productDbPromise = productRef.set(newProduct)
    const productImagePromise = fb.storage().ref(`products/${productRef.key}.${imageExt}`).put(image)
      .then(fileData => fileData.ref.getStorage().getDownloadURL())

    const [fbSnapshot, imageSrc] = await Promise.all([productDbPromise, productImagePromise])
    await fbSnapshot.ref.update({ imageSrc })

    commit('SET_LOADING', false)
    commit('CREATE_PRODUCT', {
      ...newProduct,
      id: productRef.key,
      imageSrc
    })
  } catch (error) {
    commit('SET_LOADING', false)
    throw error
  }
}

fetchProducts 中,只对产品树进行一次迭代(而不是在整个产品树上使用val(),迭代所有键的列表,然后对每个值再次迭代)。这会占用更少的 RAM,并且会更快捷。此外,您应该考虑对产品进行分页,而不是一次退回所有产品。

async fetchProducts ({ commit }) {
  commit('SET_LOADING', true)
  try {
    const resultProducts = []
    const allProductsSnapshot = await fb.database().ref('products').once('value')
    allProductsSnapshot.forEach((productSnapshot) => {
      const product = productSnapshot.val();
      resultProducts.push(
        new Product(product.title, product.price, product.description, product.ownerId, product.imageSrc, productSnapshot.key)
      )
    });

    commit('LOAD_PRODUCTS', resultProducts)
    commit('SET_LOADING', false)
  } catch (error) {
    commit('SET_LOADING', false)
    throw error
  }
}

【讨论】:

  • 感谢指正!:) 为什么重新加载页面后加载的照片可能无法显示?
  • @expromt192 找到了!您对new Product() 的论点顺序错误。
猜你喜欢
  • 2018-06-06
  • 1970-01-01
  • 1970-01-01
  • 2021-05-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-07
  • 2019-12-23
相关资源
最近更新 更多