How can i resolve "Expected first argument to collection() to be a CollectionReference, a DocumentReference or FirebaseFirestore"

Viewed 13

i am studying with 'instagram clone coding by sonny sangha in the youtube.

when i tring to upload the post with firebase, there is a error like this. i already check similar error solutions in Google, But i cannot resolve the problem. This is my first time to study with react making a project. Pleas help me out!

Given the following code:

    import { useRecoilState } from "recoil";
import { modalState } from "../atoms/modalAtom";
import {Dialog, Transition} from "@headlessui/react";
import { Fragment, useRef, useState } from "react";
import { CameraIcon } from "@heroicons/react/outline";
import { db, storage} from "../firebase";
import { 
    addDoc, 
    collection,
    doc,
    serverTimestamp, 
    updateDoc 
} from "@firebase/firestore"; 
import {useSession} from "next-auth/react";
import {ref, getDownloadURL, uploadString } from "@firebase/storage";

function Modal(){

    const {data: session} = useSession();
    const[open, setOpen] = useRecoilState(modalState);
    const filePickerRef =useRef(null);
    const captionRef = useRef(null);
    const [loading, setLoading] = useState(false);
    const [selectedFile, setSelectedFile] = useState(null);

    const uploadPost = async() => {
        if(loading) return;

        setLoading(true);

        // 1) Create a post -> add to firestore 'posts' collection
        // 2) get the post id for the newly created post
        // 3) upload the image fo firebase storage with the post id
        // 4) get the download url from db storage and update the original post with img

        const docRef = await addDoc(collection(db, 'posts'), {
            username: session.user.username,
            caption: captionRef.current.value,
            profileImg: session.user.image,
            timestamp: serverTimestamp()
        })

        console.log("new doc add with id", docRef.id);

        //3)
        const imageRef = ref(storage, `posts/${docRef.id}/image`);

        await uploadString(imageRef, selectedFile, "data_url").then(
            async (snapshot) => {
            const downloadURL = await getDownloadURL(imageRef);
            
            //4)
            await updateDoc(doc(db, 'posts',docRef.id), {
                image: downloadURL
                })
            }
        );

        setOpen(false);
        setLoading(false);
        setSelectedFile(null);

    };


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

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

    return (
    <Transition.Root show={open} as={Fragment}> 
        <Dialog
            as='div'
            className='fixed z-10 inset-0 overflow-y-auto'
            onClose={setOpen}
        >
            <div className="flex items-end justify-center min-h-[800px] sm:min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0">
                <Transition.Child
                    as={Fragment}
                    enter="ease-out duration-300"
                    enterFrom="opacity-0"
                    enterTo="opacity-100"
                    leave="ease-in duration-200"
                    leaveFrom="opacity-100"
                    leaveTo="opacity-0"
                >

                    <Dialog.Overlay 
                        className="fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity" />
                </Transition.Child>


                <span
                    className="hidden sm:inline-block sm:align-middle sm:h-screen"
                    aria-hidden="true"
                >
                    &#8203;
                </span>

                <Transition.Child
                    as={Fragment}
                    enter="ease-out duration-300"
                    enterFrom="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
                    enterTo="opacity-100 translate-y-0 sm:scale-100"
                    leave="ease-in duration-200"
                    leaveFrom="opacity-100 translate-y-0 sm:scale-100"
                    leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
                >
                    <div className="inline-block align-bottom bg-white rounded-lg px-4 pt-5 
                    pb-4 text-left overflow-hidden shadow-xl transform transition-all 
                    sm:align-middle sm:max-w-sm sm:w-full sm:p-6">

                        <div>

                            {selectedFile ? (
                                <img 
                                    src = {selectedFile} 
                                    className="w-full object-contain cursor-pointer"
                                    onClick={() => setSelectedFile(null)} 
                                    alt="" 
                                />

                            ): (

                            <div 
                                onClick = { ()=> filePickerRef.current.click() }
                                className = "mx-auto flex items-center justify-center h-12 w-12 rounded-full bg-red-100 cursor-pointer"
                                        >
                                
                                <CameraIcon 
                                    className = "h-6 w-6 text-red-600"
                                    aria-hidden="true"
                                />
                            </div>

                            )}

                            
                
                            <div>
                                <div className="mt-3 text-center sm:mt-5">
                                    <Dialog.Title
                                        as="h3"
                                        className="text-lg leading-6 font-medium  text-gray-900"
                                        >
                                            Upload a photo
                                    </Dialog.Title>

                                    <div>
                                        <input 
                                            ref={filePickerRef}
                                            type="file"
                                            hidden
                                            onChange={addImageToPost}
                                        />
                                    </div>

                                    <div className="mt-2">
                                        <input 
                                            className="border-none focus:ring-0 w-full text-center"
                                            type="text"
                                            ref={captionRef}
                                            placeholder="Please enter a caption..."
                                        />
                                    </div>
                                </div>
                            </div>

                            {/* flex justify-center space-x-4 mt-4 */}
                            <div className="mt-5 sm:mt-6">
                                <button
                                    type="button"
                                    disabled={!selectedFile}
                                    classname="inline-flex justify-center w-full rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 
                                    focus:ring-offset-2 focus:ring-red-500 sm:text-sm disabled:bg-gray-300
                                    disabled: cursor-not-allowed hover:disabled:bg-gray-300"
                                    onClick={uploadPost}
                                    >
                                    {loading ? "Uploading..." : "Upload Post"}
                                </button>
                            </div>
                        </div>
                    </div>
                </Transition.Child>
            </div>
        </Dialog>
    </Transition.Root>
    );
}

export default Modal;

The output(error) is:

> FirebaseError: Expected first argument to collection() to be a CollectionReference, a DocumentReference or FirebaseFirestore

This is the firebase.js

// Import the functions you need from the SDKs you need
import { initializeApp } from "firebase/app";
// TODO: Add SDKs for Firebase products that you want to use
// https://firebase.google.com/docs/web/setup#available-libraries

// Your web app's Firebase configuration
const firebaseConfig = {
  apiKey: "AIzaSyCI5m2ODKR0dwo-1ZuzULMI84UoqpfG_-E",
  authDomain: "instagram-fcc31.firebaseapp.com",
  projectId: "instagram-fcc31",
  storageBucket: "instagram-fcc31.appspot.com",
  messagingSenderId: "227919580465",
  appId: "1:227919580465:web:a4dbf4f84cd87b59dff410"
};

// Initialize Firebase
const app = initializeApp(firebaseConfig);
0 Answers
Related