Я просматриваю видеоурок о Nextjs и вижу, что версия Firebase, которую он использует, устарела. Мне удалось выполнить все шаги, прочитав документацию, пока я не дошел до этого момента.
Искал здесь и нашел несколько интересных ответов о том, как добиться возможности загрузки изображений в Firebase. Вот ссылка
Перепробовали все решения, и ни одно из них не сработало. Я получаю сообщение об ошибке:
FirebaseError: Firebase Storage: An unknown error occurred, please check the error payload for server response. (storage/unknown)
Bad Request
Вот код, который я пытаюсь:
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>
Не сердись на меня. Я действительно пытался сделать все возможное, чтобы найти решение и не публиковать здесь.
Любая помощь будет очень признательна, потому что я не могу понять, что не так, потому что, как упоминалось ранее, я пробовал все варианты, которые нашел до сих пор.
BTW также пытался назначить хранилище для getStorage() до const storageRef = ref(storage, `posts/${document.id}`);
Вот так:
.then((document) => {
if (imageToPost) {
const storage = getStorage();
const storageRef = ref(storage, `posts/${document.id}`);
<MORE CODE>
И мой firebase.jsфайл:
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 };



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Попробуй это. Я использовал 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.info(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.info('Upload is ' + progress + '% done');
switch (snapshot.state) {
case firebase.storage.TaskState.PAUSED: // or 'paused'
console.info('Upload is paused');
break;
case firebase.storage.TaskState.RUNNING: // or 'running'
console.info('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.info('File available at', downloadURL);
docRef.set({
message: inputRef.current.value,
name: session.user.name,
email: session.user.email,
image: downloadURL,
});
});
}
);Если вы не хотите, чтобы процесс загрузки и ошибка отображались, вы можете избавиться от этих кодов и сразу перейти к getDownloadURL.
Замените этот код из этой строки const colRef = collection(db, "posts") на removeImage();}})
Измените имя коллекции и imageToPost в соответствии с вашим кодом.
Извините, что прерываю вас, но в моем коде нет названия коллекции. А какое должно быть imageToPost.name? В моем коде нет ничего, указывающего на это. Еще раз извините, что отнял у вас время. Непонятно, что мне нужно изменить в вашем коде, чтобы он работал на моем. Я просто понимаю, что нужно взять ваш код и опубликовать его после const colRef = collection(db, "posts") до removeImage();ПРИМЕЧАНИЕ. У меня есть оператор if (if (imageToPost)), где внутри находится removeImage(), поэтому для меня это не имеет смысла... Опять же, извините, что отнимаю ваше время.
Вы упомянули «сообщения» в качестве названия своей коллекции. Надеюсь, ты прав. Нет необходимости менять «imageToPost.name». Вызовите этот метод removeImage() после inputRef.current.value = "";
Не следуйте слепо видеоуроку. Поймите основы. Счастливого обучения
Спасибо за уточнение. Я понимаю основы, просто я вижу, что ваша структура кода сильно отличается от той, которую я опубликовал. Очень ценю ваши усилия, чтобы помочь мне :)
Я получаю TypeError: firebase_app__WEBPACK_IMPORTED_MODULE_6__.firestore is not a function, указывающий на const docRef = firebase.firestore().collection("posts").doc(); Imported import * as firebase from "firebase/app";, но не могу решить эту проблему.
Какую версию firebase вы используете?
Если v8, то импортируйте как этот import firebase from "firebase/app" // Добавьте продукты Firebase, которые вы хотите использовать import "firebase/firestore" import "firebase/storage" Если вы используете v9, это не будет работать. Вам нужно изменить много вещей в соответствии с v9.
Хорошо, я использую firebase версии 9.13.0. Нужно найти другой способ добиться этого.
Логика такая же и в v9. Но вы должны импортировать метод v9 и использовать его в соответствии с ним. Вы можете сослаться на документы firebase для этого.
Да, я читаю документы и делаю, как они говорят. Но все равно получаю эту ошибку... [stackoverflow.com/questions/70052479/… нашел и другой случай с такой же ошибкой
Попробуйте это, это сработало для меня: 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 = "";
Спасибо. Должен ли этот код заменить весь код внутри
const sendPost = async (e) => {? Ценить