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"
>
​
</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);