skip to Main Content

I’m following a video tutorial about Nextjs and have seen that the version of Firebase he is using is out of date. I managed to follow all the steps reading the documentation until I got to this point.

Searched here and found some interesting answers on how to achieve the option to upload images to Firebase. Here the link

Have tried all solutions and none of them have worked. I get an error message:


FirebaseError: Firebase Storage: An unknown error occurred, please check the error payload for server response. (storage/unknown)
Bad Request

Here the code I’m trying:

import Image from "next/image";
import { useSession } from "next-auth/react";
import { FaceSmileIcon } from "@heroicons/react/24/outline";
import { VideoCameraIcon, PhotoIcon } from "@heroicons/react/20/solid";
import { useRef } from "react";
import { db, storage } from "../firebase";
import { collection, addDoc, serverTimestamp, doc, setDoc } from "firebase/firestore";
import { useState } from "react";
import {ref, uploadString, getDownloadURL, getStorage} from "firebase/storage";

function InputBox() {

    const {data: session} = useSession();
    const inputRef = useRef(null);
    const filePickerRef = useRef(null);
    const [imageToPost, setImageToPost] = useState(null);

    const sendPost = async (e) => {
        e.preventDefault();
        if(!inputRef.current.value) return;

        const colRef = collection(db, "posts")

        await addDoc(colRef, {
            message: inputRef.current.value,
            name: session.user.name,
            email: session.user.email,
            image: session.user.image,
            timestamp: serverTimestamp(),
        }).then((document) => {
            if(imageToPost) {
                const storageRef = ref(storage, `posts/${document.id}`);
                uploadString(storageRef, imageToPost, "data_url").then((snapshot) => {
                    getDownloadURL(snapshot.ref).then(URL => {
                        setDoc(doc(db, "posts", document.id), 
                        {imageToPost: URL}, {merge: true}
                        );
                    });
                })
                removeImage();
            }
        })
        inputRef.current.value = "";
    };

    const addImageToPost = (e) => {
        const reader = new FileReader();
        if(e.target.files[0]) {
            reader.readAsDataURL(e.target.files[0]);
        }

        reader.onload = (readerEvent) => {
            setImageToPost(readerEvent.target.result);
        }
    };

    const removeImage = () => {
        setImageToPost(null);
    };

    return ( <HERE THE REST OF THE CODE>

Don’t be mad at me. I really tried to do my best to find a solution and to not post here.

Any help will be really appreciated because I can’t figure out what is wrong, because as mentioned before I tried all options I found so far.

BTW also tried to assign storage to getStorage() before const storageRef = ref(storage, `posts/${document.id}`);

Like so:

.then((document) => {
   if(imageToPost) {
      const storage = getStorage();
      const storageRef = ref(storage, `posts/${document.id}`);

<MORE CODE>

And my firebase.jsfile:

import { initializeApp } from 'firebase/app';
import { getStorage } from "firebase/storage";

const firebaseConfig = {
    apiKey: "APIKEY-HERE",
    authDomain: "AUTHDOMAIN-HERE",
    projectId: "PROJECT-ID-HERE",
    storageBucket: "STORAGE-BUCKET-HERE",
    messagingSenderId: "MESSAGING-SENDER-HERE",
    appId: "APPID-HERE"
  };


  const app = initializeApp(firebaseConfig);
  const db = getFirestore(app);

  const storage = getStorage(app);

  export { db, storage };

2

Answers


  1. Try this. I have used firebase v8.6.3.

    const docRef = firebase.firestore().collection("colection_name").doc();
    const storageRef = firebase.storage().ref();
    const uploadTask = storageRef.child('/posts/' + imageToPost.name).put(imageToPost);
    console.log(uploadTask)
    uploadTask.on(firebase.storage.TaskEvent.STATE_CHANGED, // or 'state_changed'
        (snapshot) => {
            // Get task progress, including the number of bytes uploaded and the total number of bytes to be uploaded
            var progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
            console.log('Upload is ' + progress + '% done');
            switch (snapshot.state) {
                case firebase.storage.TaskState.PAUSED: // or 'paused'
                    console.log('Upload is paused');
                    break;
                case firebase.storage.TaskState.RUNNING: // or 'running'
                    console.log('Upload is running');
                    break;
            }
        },
        (error) => {
            // A full list of error codes is available at
            // https://firebase.google.com/docs/storage/web/handle-errors
            switch (error.code) {
                case 'storage/unauthorized':
                    // User doesn't have permission to access the object
                    break;
                case 'storage/canceled':
                    // User canceled the upload
                    break;
    
                // ...
    
                case 'storage/unknown':
                    // Unknown error occurred, inspect error.serverResponse
                    break;
            }
        },
        () => {
            // Upload completed successfully, now we can get the download URL
            uploadTask.snapshot.ref.getDownloadURL().then((downloadURL) => {
                console.log('File available at', downloadURL);
                docRef.set({
                    message: inputRef.current.value,
                    name: session.user.name,
                    email: session.user.email,
                    image: downloadURL,
                });
            });
        }
    );

    If you don’t want the upload progress and error then you can get rid of that codes and directly proceed to getDownloadURL.

    Login or Signup to reply.
  2. Try this, this worked for me: Firebase: "^9.0.0"

    addDoc(dbInstance, {
          message: inputRef.current.value,
          name: session?.user?.name,
          email: session?.user?.email,
          image: session?.user?.image,
          timestamp: serverTimestamp(),
        }).then((doc) => {
          if (imageToPost) {
            const storageRef = ref(storage, `posts/${doc.id}`);
    
            uploadString(storageRef, imageToPost, "data_url").then((snapshot) => {
              getDownloadURL(snapshot.ref).then((url) => {
                addDoc(dbInstance, { postImage: url });
              });
            });
    
            removeImage();
          }
        });
    
        inputRef.current.value = "";
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search