最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How do I connect Firebase Storage with Cloud Firestore so my images are associated to their respective posts? - Sta

programmeradmin0浏览0评论

I have a CRUD React app where you can create articles. There is a 'title', 'content' and 'image'.

I have a collection in Cloud Firestore called 'articles'. The documents have the fields: 'title' and 'content' so every time I create an article in my react app, a new document is created.

The next step was to be able to add images to the articles.

I managed to connect to Firebase and upload an image to Firebase Storage from my React page. However how do I connect the images to their articles? Like, how do I make the connection between Cloud Firestore and Storage?

Do I create an extra field in my documents called 'images'? But then how do I reference it? I also want to try and avoid duplicates.

UploadImage.js


import React, { useState, Component } from "react";
import { storage } from "../Firebase";

function UploadFile() {
        const [image, setImage] = useState(null);
        const [url, setUrl] = useState("");
        const [progress, setProgress] = useState(0);

        const handleChange = e => {
            if (e.target.files[0]) {
              setImage(e.target.files[0]);
            }
          };

          const handleUpload = () => {
            const uploadTask = storage.ref(`images/${image.name}`).put(image);
            uploadTask.on(
              "state_changed",
              snapshot => {
                const progress = Math.round(
                  (snapshot.bytesTransferred / snapshot.totalBytes) * 100
                );
                setProgress(progress);
              },
              error => {
                console.log(error);
              },
              () => {
                storage
                  .ref("images")
                  .child(image.name)
                  .getDownloadURL()
                  .then(url => {
                    setUrl(url);
                  });
              }
            );
          };

          console.log("image: ", image);

      return (
        <div>
      <progress value={progress} max="100" />
      <br />
      <br />
      <input type="file" onChange={handleChange} />
      <button onClick={handleUpload}>Upload</button>
      <br />
      {url}
      <br />
      <img src={url || ";} alt="firebase-image" />
    </div>
         
      );
    }

    export default UploadFile;

This is my 'Add Article' form-->

AddArticle.js

import React, { Component } from 'react';
import firebase from '../Firebase';
import UploadFile from '../ponents/UploadFile';

class AddArticle extends Component {

  constructor() {
    super();
    this.ref = firebase.firestore().collection('articles');
    this.state = {
      title: '',
      content: ''
    };
  }
  onChange = (e) => {
    const state = this.state
    state[e.target.name] = e.target.value;
    this.setState(state);
  }

  onSubmit = (e) => {
    e.preventDefault();

    const { title, content } = this.state;

    this.ref.add({
      title,
      content

    }).then((docRef) => {
      this.setState({
        title: '',
        content: ''
      });
      this.props.history.push("/")
    })
    .catch((error) => {
      console.error("Error adding document: ", error);
    });
  }

  render() {
    const { title, content } = this.state;
    return (
      <div className="container">
      <br></br><br></br><br></br>
        <div className="panel panel-default">
          <div className="panel-heading">
            <h3 className="panel-title text-center">
              Create a new article
            </h3>
          </div>
          <br></br><br></br>
          <div className="panel-body">
            <form onSubmit={this.onSubmit}>
              <div className="form-group">
                <label for="title">Title:</label>
                <input type="text" className="form-control" name="title" value={title} onChange={this.onChange} placeholder="Title" />
              </div>
              <div className="form-group">
                <label for="content">Content:</label>
                <textArea className="form-control" name="content" onChange={this.onChange} placeholder="Content" cols="80" rows="20">{content}</textArea>
              </div>
              <UploadFile />
              <button type="submit" className="btn btn-success">Submit</button>
            </form>
          </div>
        </div>
      </div>
    );
  }
}

export default AddArticle;

I have a CRUD React app where you can create articles. There is a 'title', 'content' and 'image'.

I have a collection in Cloud Firestore called 'articles'. The documents have the fields: 'title' and 'content' so every time I create an article in my react app, a new document is created.

The next step was to be able to add images to the articles.

I managed to connect to Firebase and upload an image to Firebase Storage from my React page. However how do I connect the images to their articles? Like, how do I make the connection between Cloud Firestore and Storage?

Do I create an extra field in my documents called 'images'? But then how do I reference it? I also want to try and avoid duplicates.

UploadImage.js


import React, { useState, Component } from "react";
import { storage } from "../Firebase";

function UploadFile() {
        const [image, setImage] = useState(null);
        const [url, setUrl] = useState("");
        const [progress, setProgress] = useState(0);

        const handleChange = e => {
            if (e.target.files[0]) {
              setImage(e.target.files[0]);
            }
          };

          const handleUpload = () => {
            const uploadTask = storage.ref(`images/${image.name}`).put(image);
            uploadTask.on(
              "state_changed",
              snapshot => {
                const progress = Math.round(
                  (snapshot.bytesTransferred / snapshot.totalBytes) * 100
                );
                setProgress(progress);
              },
              error => {
                console.log(error);
              },
              () => {
                storage
                  .ref("images")
                  .child(image.name)
                  .getDownloadURL()
                  .then(url => {
                    setUrl(url);
                  });
              }
            );
          };

          console.log("image: ", image);

      return (
        <div>
      <progress value={progress} max="100" />
      <br />
      <br />
      <input type="file" onChange={handleChange} />
      <button onClick={handleUpload}>Upload</button>
      <br />
      {url}
      <br />
      <img src={url || "http://via.placeholder./300"} alt="firebase-image" />
    </div>
         
      );
    }

    export default UploadFile;

This is my 'Add Article' form-->

AddArticle.js

import React, { Component } from 'react';
import firebase from '../Firebase';
import UploadFile from '../ponents/UploadFile';

class AddArticle extends Component {

  constructor() {
    super();
    this.ref = firebase.firestore().collection('articles');
    this.state = {
      title: '',
      content: ''
    };
  }
  onChange = (e) => {
    const state = this.state
    state[e.target.name] = e.target.value;
    this.setState(state);
  }

  onSubmit = (e) => {
    e.preventDefault();

    const { title, content } = this.state;

    this.ref.add({
      title,
      content

    }).then((docRef) => {
      this.setState({
        title: '',
        content: ''
      });
      this.props.history.push("/")
    })
    .catch((error) => {
      console.error("Error adding document: ", error);
    });
  }

  render() {
    const { title, content } = this.state;
    return (
      <div className="container">
      <br></br><br></br><br></br>
        <div className="panel panel-default">
          <div className="panel-heading">
            <h3 className="panel-title text-center">
              Create a new article
            </h3>
          </div>
          <br></br><br></br>
          <div className="panel-body">
            <form onSubmit={this.onSubmit}>
              <div className="form-group">
                <label for="title">Title:</label>
                <input type="text" className="form-control" name="title" value={title} onChange={this.onChange} placeholder="Title" />
              </div>
              <div className="form-group">
                <label for="content">Content:</label>
                <textArea className="form-control" name="content" onChange={this.onChange} placeholder="Content" cols="80" rows="20">{content}</textArea>
              </div>
              <UploadFile />
              <button type="submit" className="btn btn-success">Submit</button>
            </form>
          </div>
        </div>
      </div>
    );
  }
}

export default AddArticle;
Share Improve this question edited Aug 13, 2020 at 18:40 Doug Stevenson 319k36 gold badges456 silver badges473 bronze badges asked Aug 13, 2020 at 18:28 cldevcldev 7819 silver badges19 bronze badges 0
Add a ment  | 

1 Answer 1

Reset to default 5

It is actually pretty simple, to achieve this follow steps below:

  1. After uploading your image to firebase storage you should get download url for that particular image (I linked firebase documentation link below on how to achieve that).

https://firebase.google./docs/storage/web/download-files

  1. If you successfully fetched download url from firebase storage now it is time to create separate field under your document named such as "postImageUrl" (you can name whatever you want) and save download url under this field.

  2. Now you can show images using this download url in your page using busboy library

https://www.npmjs./package/busboy

Note: I am an Android Developer so I tried my best to help. If you have further questions don't hesitate to ask

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论