【问题标题】:How to Upload Image to Firebase Storage and Upload URL to Firestore simultaneously in React.js?如何在 React.js 中同时将图像上传到 Firebase 存储并将 URL 上传到 Firestore?
【发布时间】:2020-07-27 15:28:58
【问题描述】:

我是 React.js 的新手, 我正在尝试将图像上传到 Firebase 存储,并在成功上传后尝试将 downloadURL 同时推送到 Firestore。怎么做?这是上传图片工作正常但firestore不工作的代码。

    import React, {useState, Component} from 'react';
    import firebase from "../firebase";

    const storage = firebase.storage();

    class ImageUpload extends Component {
      constructor(props) {
        super(props);
        this.state = {
          image: null,
          url: '',
          progress: 0
        }
        this.handleChange = this
          .handleChange
          .bind(this);
          this.handleUpload = this.handleUpload.bind(this);
      }
      handleChange = e => {
        if (e.target.files[0]) {
          const image = e.target.files[0];
          this.setState(() => ({image}));
        }
      }
      handleUpload = () => {
          const {image} = this.state;
          const uploadTask = storage.ref(`images/${image.name}`).put(image);
          uploadTask.on('state_changed',
          (snapshot) => {
            // progrss function ....
            const progress = Math.round((snapshot.bytesTransferred / snapshot.totalBytes) * 100);
            this.setState({progress});
          },
          (error) => {
               // error function ....
            console.log(error);
          },
        () => {
            // complete function ....
            storage.ref('images').child(image.name).getDownloadURL().then(url => {
                console.log(url);
                this.setState({url});

//************************** 这部分不工作(开始) *********** ************************

                const [imgURL, setImgURL] = useState('')

                firebase
                .firestore()
                .collection('notes')
                .add({
                  imgURL
                })
                .then(() => {
                  setImgURL('')
                })

//******************************这部分不起作用(END)******* *************************

            })
        });
      }
      render() {

        return (
          <div>
          <progress value={this.state.progress} max="100"/>
          <br/>
            <input type="file" onChange={this.handleChange}/>
            <button onClick={this.handleUpload}>Upload</button>
            <br/>

            <img src={this.state.url || 'http://via.placeholder.com/400x300'} alt="Uploaded images" height="300" width="400"/>
          </div>
        )
      }
    }
    export default ImageUpload;

【问题讨论】:

    标签: reactjs firebase google-cloud-firestore firebase-storage


    【解决方案1】:

    要将下载 URL 写入数据库,您不需要将其存储在 state 中。您可以直接在 then 处理程序中将其写入数据库:

    storage.ref('images').child(image.name).getDownloadURL().then(url => {
        firebase
        .firestore()
        .collection('notes')
        .add({
          imgURL: url
        })
        .then(() => {
          setImgURL('')
        })
    });
    

    【讨论】:

    • 但是上传完成后,进度条没有设置为0。我该怎么做?
    【解决方案2】:

    confing.js

    import firebase from 'firebase/app'
    import "firebase/firestore";
    import "firebase/storage";
    
    const firebaseConfig = {
                apiKey: "XXXX",
                authDomain: "XXXXX.firebaseapp.com",
                databaseURL: "https://XXXX-app-web.firebaseio.com",
                projectId: "XXXX",
                storageBucket: "XXXX-app-web.appspot.com",
                messagingSenderId: "XXXXXX",
                appId: "1:XXX:web:XXXX",
                measurementId: "G-XXXX"
    };
    firebase.initializeApp(firebaseConfig);
    export const firestore = firebase.firestore();
    export const storageRef = firebase.storage();
    
    export default firebase;
    

    Button.js

    import React from 'react';
    import {firestore,storageRef} from './Config';
    import Card from './Components/Card';
    import {Fab, Grid} from '@material-ui/core';
    import {Add} from '@material-ui/icons';
    
    function guidGenerator() {
        const S4 = function () {
            return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
        };
        return (S4() + S4() + "-" + S4() + "-" + S4() + "-" + S4() + "-" + S4() + S4() + S4());
    
    }
    
    export default function MediaCard(props) {
    const fileUpload = (e) => {
            const file = e.target.files[0];
            console.log("FileName", file)
            const uploadTask = storageRef.ref('All_Files/').child(file.name).put(file);
    
            uploadTask.on('state_changed',
                (snapshot) => {
                    const progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
                    console.log('Upload is ' + progress + '% done');
                },
                (error) => {
                    // Handle unsuccessful uploads
                    console.log("error:-", error)
                },
                () => {
                    const uniId = guidGenerator().toString();
                    // Handle successful uploads on complete
                    // For instance, get the download URL: https://firebasestorage.googleapis.com/...
                    uploadTask.snapshot.ref.getDownloadURL().then((downloadURL) => {
                        console.log('File available at', downloadURL);
                        firestore.collection("All_Files").doc(uniId).set({
                            file_name: file.name.toString(),
                            id: uniId,
                            download_url: downloadURL.toString()
                        })
                            .then(() => {
                                console.log("Document successfully written!");
                            })
                            .catch((error) => {
                                console.error("Error writing document: ", error);
                            });
                    });
                }
            );
      return (
        <>
               <div>
                    <Fab
                        color="primary"
                        aria-label="add"
                        style={{position: "fixed", bottom: "30px", right: "50px"}}
                    >
                        <input hidden className={classes.input} id="icon-button-file" onChange={fileUpload} type="file"/>
                        <label htmlFor="icon-button-file" style={{height: "24px"}}>
                            <Add/>
                        </label>
                    </Fab>
                </div>
        </>
      );
    }
    

    【讨论】:

      猜你喜欢
      • 2019-07-24
      • 2022-01-04
      • 1970-01-01
      • 2017-03-27
      • 2017-09-25
      • 2021-03-14
      相关资源
      最近更新 更多