通过Web应用访问Firebase存储(照片)的方法 [英] Ways to access firebase storage (photos) via web app

本文介绍了通过Web应用访问Firebase存储(照片)的方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于使用React Redux Firebase Web应用程序访问Firebase存储中存储的一堆图像的适当方法,我感到困惑.简而言之,我很想了解一下,一旦将照片上传到Firebase存储中,您将如何将其链接到Firebase数据库(如从存储中返回的快照中的确切内容),然后访问它(如果不只是< img src = {data.downloadURL}/> ),还可以访问(如果需要)在照片被覆盖时更新该链接的方式.如果您可以回答,请随时跳过其余内容...

I'm confused as to the appropriate way to access a bunch of images stored in Firebase storage with a react redux firebase web app. In short, I'd love to get a walkthrough of, once a photo has been uploaded to firebase storage, how you'd go about linking it to a firebase db (like what exactly from the snapshot returned you'd store), then access it (if it's not just <img src={data.downloadURL} />), and also how you'd handle (if necessary) updating that link when the photo gets overwritten. If you can answer that, feel free to skip the rest of this...

我遇到的两个选择是

  1. 将完整URL存储在我的Firebase数据库中,或
  2. 存储更少的东西,例如存储桶中的路径,然后为每张照片调用downloadURL()……这似乎是不必要的流量,不是吗?

此刻我的数据库结构如下:

My db structure at the moment is like so:

{
  <someProjectId>:  {
    imgs: {
      <someAutoGenId>: {
        "name":"photo1.jpg",
        "url":"https://<bucket, path, etc>token=<token>"
      },
      ...
    },
    <otherProjectDetails>: "",
    ...
  },
  ...
}

继续使用该结构和列出的第一个想法,当照片被覆盖时我遇到了麻烦,因此我需要遍历图像列表并删除与名称匹配的db记录(或查找并更新)其网址).我可以做到这一点(最多有两个ref需要替换掉旧标记),但是后来我看到人们通过选项2做到了,尽管不一定要根据我的实际情况.

Going forward with that structure and the first idea listed, I ran into trouble when a photo was overwritten, so I would need to go through the list of images and remove the db record that matches the name (or find it and update its URL). I could do this (at most, there would be two refs with the old token that I would need to replace), but then I saw people doing it via option 2, though not necessarily with my exact situation.

我最后几次看到的是类似的问题,指向Cloud Functions的通用回答,我将在发布后立即进行调查,但是我不确定这是否会使我的情况变得过于复杂,所以我认为问这个问题不会太大.我最初了解/了解了Cloud Functions,并了解了Firebase的数据库是实时"的事实,但不确定在React/Redux环境中能否正常运行.无论如何,我将不胜感激,谢谢.

推荐答案

在研究Cloud Functions时,我意识到使用Cloud Functions并不是一个完全独立的选择,而是一种实现上面列出的第一个选项的方式(也可能是第二个).我确实尽力澄清了这一点,但我很有信心我失败了,所以我深表歉意.这是我的(两部分)工作解决方案,用于将Firebase DB中的引用同步到Firebase存储url(在React Redux Web App中,尽管我认为无论如何都应适用第一部分):

In researching Cloud Functions, I realized that the use of Cloud Functions wasn't an entirely separate option, but rather a way to accomplish the first option I listed above (and probably the second as well). I really tried to make this clear, but I'm pretty confident I failed... so my apologies. Here's my (2-Part) working solution to syncing references in Firebase DB to Firebase Storage urls (in a React Redux Web App, though I think Part One should be applicable regardless):

一个部分

按照此处 https://firebase.google.com/docs/functions/入门以启用云功能.

Follow along here https://firebase.google.com/docs/functions/get-started to get cloud functions enabled.

我存储的与图像有关的信息的数据库部分位于/projects/detail/{projectKey}/imgs 并具有以下结构:

The part of my database with the info I was storing relating to the images was at /projects/detail/{projectKey}/imgs and had this structure:

{< autoGenKey1> ;: {名称:"image1.jpg",网址:< longURLWithToken>},< moreAutoGenKeys> ;: {...},...}

我的云功能如下:

exports.updateURLToken = functions.database.ref(`/projects/detail/{projectKey}/imgs`)
  .onWrite(event => {

    const projectKey = event.params.projectKey
    const newObjectSet = event.data.val()
      const newKeys = Object.keys(newObjectSet)
    const oldObjectSet = event.data.previous.val()
      const oldKeys = Object.keys(oldObjectSet)
    let newObjectKey = null

    // If something was removed, none of this is necessary - return
    if (oldKeys.length > newKeys.length) {
      return null
    }

    for (let i = 0; i < newKeys.length; ++i) {// Looking for the new object -> will be missing in oldObjectSet
      const key = newKeys[i]
      if (oldKeys.indexOf(key) === -1) {// Found new object
        newObjectKey = key
        break
      }
    }

    if (newObjectKey !== null) {// Checking if new object overwrote an existing object (same name)
      const newObject = newObjectSet[newObjectKey]
      let duplicateKey = null
      for (let i = 0; i < oldKeys.length; ++i) {
        const oldObject = oldObjectSet[oldKeys[i]]
        if (newObject.name === oldObject.name) {// Duplicate found
          duplicateKey = oldKeys[i]
          break
        }
      }

      if (duplicateKey !== null) {// Remove duplicate
        return event.data.ref.child(duplicateKey).remove((error) => error ? 'Error removing duplicate project detail image' : true)
      }
    }

    return null
  })

加载此功能后,它将在该位置( projects/detail/{projectKey}/imgs )上进行任何更改时都将运行.因此,我上传了图像,并使用名称和url在数据库中添加了一个新对象,这将查找已创建的新对象,如果名称重复,则会从数据库中删除具有相同名称的旧对象.

After loading this function, it would run every time anything changed at that location (projects/detail/{projectKey}/imgs). So I uploaded the images, added a new object to my db with the name and url, then this would find the new object that was created, and if it had a duplicate name, that old object with the same name was removed from the db.

两个部分

因此,现在我的数据库具有正确的信息,但是除非我在每次上传图像后刷新页面,否则将新对象添加到数据库中(本地)会导致我仍然拥有所有重复的引用,这就是实时数据库开始发挥作用.

So now my database had the correct info, but unless I refreshed the page after every time images were uploaded, adding the new object to my database resulted (locally) in me having all the duplicate refs still, and this is where the realtime database came in to play.

在我的容器内,我有:

function mapDispatchToProps (dispatch) {
  syncProjectDetailImages(dispatch) // the relavant line -> imported from api.js
  return bindActionCreators({
    ...projectsContentActionCreators,
    ...themeActionCreators,
    ...userActionCreators,
  }, dispatch)
}

然后我的api.js拥有该syncProjectDetailImages函数:

Then my api.js holds that syncProjectDetailImages function:

const SAVING_PROJECT_SUCCESS = 'SAVING_PROJECT_SUCCESS'
export function syncProjectDetailImages (dispatch) {
  ref.child(`projects/detail`).on('child_changed', (snapshot) => {
    dispatch(projectDetailImagesUpdated(snapshot.key, snapshot.val()))
  })
}
function projectDetailImagesUpdated (key, updatedProject) {
  return {
    type: SAVING_PROJECT_SUCCESS,
    group: 'detail',
    key,
    updatedProject
  }
}

最后,在我的模块文件夹中找到了调度(我使用了与使用redux保存更新项目的任何部分时相同的功能-不需要新代码)

And finally, dispatch is figured out in my modules folder (I used the same function I would when saving any part of an updated project with redux - no new code was necessary)

这篇关于通过Web应用访问Firebase存储(照片)的方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆