Home > Back-end >  How can I put the file in Firebase Storage? - React
How can I put the file in Firebase Storage? - React

Time:09-22

I'm having a hard time putting the file in firebase so I can retrieve its getDownloadURL.

Here's what I got

import React, {useState, useEffect} from 'react'
import { Container, Button, Row, Col, Form, Alert } from 'react-bootstrap'
import PageHeader from '../components/PageHeader'
import { projectFirestore, projectStorage } from '../firebase/config'

const Dashboard = () => {
  const [ error, setError] = useState('')
  const [ name, setName ] = useState("")
  const [ link, setLink ] = useState("")
  const [ file, setFile ] = useState(null)
  const [ desc, setDesc ] = useState("")
  const [ projects, setProjects ] = useState([])
  const [ url, setUrl ] = useState("")

  const [ message, setMessage ] = useState("")

  useEffect(() => {
    projectFirestore.collection('projects').onSnapshot((snapshot) =>{
      const tempProject = []
      snapshot.forEach(doc => {
        tempProject.push({...doc.data(), id: doc.id});
      })
      setProjects(tempProject)
    })
  }, [])

  const onNameChange = (e) => { setName(e.target.value) }
  const onLinkChange = (e) => { setLink(e.target.value) }
  const onDescChange = (e) => { setDesc(e.target.value) }

  const handleSubmit = async (e) => {
    e.preventDefault()
    try {
      setMessage('')
      setError('')

      if(!name){
        return
      }

      const storageRef = projectStorage.ref()
      const fileRef = storageRef.child(file.name)
      await fileRef.put(file)
      
      setUrl(fileRef.getDownloadURL())
      projectFirestore.collection('projects')
        .doc( name, link, url, desc )
        .set({ name, link, url, desc })
        

      setMessage('Project added succesfully')

      setName('')
      setLink('')
      setFile(null)
      setDesc('')
    } catch {
      setError('Project fail to add')
    }
  }

  return (
    <div className="">
      <Container>
        <PageHeader title="Dashboard" />
        
        <Row>
          <Col xs={12}>
            <h4>Add Project</h4>
            {message && <Alert variant="success">{message}</Alert> }
            {error && <Alert variant="danger">{error}</Alert> }
            <Form onSubmit={handleSubmit}>
              <Row>
                <Col xs={12} lg={8}>
                  <Form.Group className="mb-3">
                    <Form.Label>Name</Form.Label>
                    <Form.Control 
                      type="text" 
                      value={name} 
                      onChange={onNameChange}/>
                  </Form.Group>
                  <Form.Group className="mb-3">
                    <Form.Label>Description</Form.Label>
                    <Form.Control 
                      as="textarea" 
                      rows={5} 
                      value={desc} 
                      onChange={onDescChange}/>
                  </Form.Group>
                  <Form.Group className="mb-3">
                    <Form.Label>Link</Form.Label>
                    <Form.Control 
                      type="text"
                      value={link} 
                      onChange={onLinkChange} />
                  </Form.Group>
                </Col>
                <Col xs={12} lg={4}>
                  <Form.Group className="mb-3">
                    <Form.Label>Image</Form.Label>
                    <Form.Control type="file" onChange={(e) => setFile(e.target.files[0])}/>
                  </Form.Group>
                  <div>
                    {projects.map(project => (                     
                      <div key={project.id} to={`/${project.id}`}>
                        <img src={project.url} alt={project.name} />
                        <h5>{project.name}</h5>
                      </div>
                    ))}
                  </div>
                </Col>
              </Row> 
              <div className="d-flex justify-content-end">
                <Button variant="primary" type="submit"> Send</Button>
              </div>
            </Form>
          </Col>
        </Row>
      </Container>
    </div>
  )
}

export default Dashboard

Storage Database

CodePudding user response:

The code looks fine but I would add some validation and check if a file is actually selected by user. The doc() method takes a string as documentID. Also getDownloadURL()returns a promise. Try refactoring the code to:

const handleSubmit = async (e) => {
  e.preventDefault()
  try {
    setMessage('')
    setError('')

    if(!name){
      return
    }

    if (!file) {
      console.log("No file selected")
      return
    }
 
    console.log("Starting file upload")
    const storageRef = projectStorage.ref()
    const fileRef = storageRef.child(file.name)
    await fileRef.put(file)
    console.log("File uploaded")   

    const fileUrl = await fileRef.getDownloadURL()
    console.log(fileUrl) 
    setUrl(fileUrl)
 
    await  projectFirestore.collection('projects')
      .doc("some_document_id")
      .set({ name, link, url: fileUrl, desc })
        

    setMessage('Project added succesfully')

    setName('')
    setLink('')
    setFile(null)
    setDesc('')
  } catch {
    setError('Project fail to add')
  }
}
  • Related