'i am trying to store the photo in the database (firebase) and in the storage. the photo got store in the Storage, but not added in the firestore

I am trying to store the photo in the database (firebase) and in the storage simultaneously. The photo got store in the Storage, but not added in the firestore. Any Help Please ?

My code below shows what I did to perform the task. Oh it is in reactJs

function Preview() {

  const cameraImage = useSelector(selectCameraImage);
  const navigate = useNavigate();
  const dispatch = useDispatch();

  // if there is no Image taken then return to homepage (navigate('../'), {replace: 
  true})
  useEffect(()=>{
      if(!cameraImage){
          navigate('../', {replace: true});
      }
  }, [navigate, cameraImage])

  const closePreview = ()=>{
      dispatch(resetCameraImage())
  }

  const sendPost = () =>{
    const id = uuid();
    const uploadTask = storage
    .ref(`posts/ ${id}`)
    .putString(cameraImage, "data_url");

    uploadTask.on('state_changed', null, (error) =>{
      //error  function
      console.log(error);
     }, 
      //COMPLETE function**this is the storage*## storage ##

        ()=>{storage
            .ref('post')
            .child(id)
            .getDownloadURL()
            .then((url) => {
                db.collection('posts').add({
                  imageUrl: url,
                  username: 'yannick Simo',
                  read: false,
                  //profilePic
                  timestamp: firebase.firestore.FieldValue.serverTimestamp(),
                });
                navigate('./chats', {replace: true});
          })
    })
   }
    return (
   <div className="preview" >
    <div onClick={sendPost} className="preview__footer">
      <h2>Send Now</h2>
      <SendIcon fontSize="small" className="preview__sendIcon" />
    </div>
  </div>);
}

export default Preview;


Solution 1:[1]

You're calling getDownloadURL on a different ref than you're uploading the image to.

The upload goes to

const uploadTask = storage
.ref(`posts/ ${id}`)
.putString(cameraImage, "data_url");

And then you get the download URL like this:

storage
.ref('post')
.child(id)
.getDownloadURL()

Note posts (plural) vs post (singular) in these references.


To prevent such mistakes, I recommend creating a single variable to hold the reference, and then using that everywhere:

const sendPost = () => {
  const id = uuid();
  const uploadRef = storage.ref(`posts/ ${id}`); // ?
  const uploadTask = ref.putString(cameraImage, "data_url"); // ?

  uploadTask.on('state_changed', null, (error) => {
      //error  function
      console.log(error);
    },
    () => {
      ref.getDownloadURL() // ?
        .then((url) => {
          db.collection('posts').add({
            imageUrl: url,
            username: 'yannick Simo',
            read: false,
            //profilePic
            timestamp: firebase.firestore.FieldValue.serverTimestamp(),
          });
          navigate('./chats', {
            replace: true
          });
        })
    })
}

As a final improvement, since you're not doing anything in the other callbacks, you can also just the fact that uploadTask is a promise itself, and use then() on it, to shorten the code and make it a bit more idiomatic:

const sendPost = () => {
  const id = uuid();
  const uploadRef = storage.ref(`posts/ ${id}`);
  const uploadTask = ref.putString(cameraImage, "data_url");

  uploadTask.then(() => { // ?
    ref.getDownloadURL()
      .then((url) => {
        db.collection('posts').add({
          imageUrl: url,
          username: 'yannick Simo',
          read: false,
          //profilePic
          timestamp: firebase.firestore.FieldValue.serverTimestamp(),
        });
        navigate('./chats', {
          replace: true
        });
      })
  }).catch((error) => console.error(error)); // ?
}

If you then use async/await of modern JavaScript, you can turn this into the even simpler to read:

const sendPost = () => async { // ?
  const id = uuid();
  const uploadRef = storage.ref(`posts/ ${id}`);
  await ref.putString(cameraImage, "data_url"); // ?

  const url = await ref.getDownloadURL() ?
  db.collection('posts').add({
    imageUrl: url,
    username: 'yannick Simo',
    read: false,
    //profilePic
    timestamp: firebase.firestore.FieldValue.serverTimestamp(),
  });
  navigate('./chats', {
    replace: true
  });
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1