Im trying to rewrite 4 lines of firebase v8 code to work with v9.... but I'm stuck on these 3 lines, even after studying Firebase documentation.... This code is found within a form submit function and taken from one of Shaun Pelling's (the Net Ninja's) Udemy Firebase/React Course.
The code serves a pretty simple purpose:
I'd like to upload the comment to a custom file path within firebase taking in the userId (uid) previously defined as a variable in the filepath. Then upload the file. In my nabber I also have an image being displayed from the url created by the 3rd line of code.
EDIT: First, here's the JSX to which the file originally is uploaded from:
<label>
<span>Upload Profile Thumbnail:</span>
<input
required
type="file"
id="thumbnail"
name="thumbnail"
/>
</label>
the original 4 lines I'm referring to (v8):
const res = await projectAuth.createUserWithEmailAndPassword(email, password)
const uploadPath = `thumbnails/${res.user.uid}/${thumbnail.name}`
const image = await projectStorage.ref(uploadPath).put(thumbnail)
const imageUrl = await image.ref.getDownloadURL()
await res.user.updateProfile({ photoURL: imageUrl })
This is kind of what I've got. (It's a mess I don't don't think it even makes much sense. I'm a bit lost, so if it confuses you as well, please disregard... I just wanted to show I'm trying \(˚☐˚”)/)
import { ref, getDownloadURL, uploadBytesResumable } from 'firebase/storage'
import { updateProfile } from 'firebase/auth'
const uploadPath = `thumbnails/${res.user.uid}/${thumbnail.name}`
const imageUrl = getDownloadURL(ref(storage, image))
const uploadTask = uploadBytesResumable(storageRef, file, metadata )
updateProfile(user, { photoURL: imageUrl})
SIDENOTE: Oh, 1 little probably much less important sidenote (and more than likely unnecessary), In the v8 example, the thumbnail is uploaded within the signup form, hence the signup function in the first bit of code. In the second example v9, I created a whole new page (only available to signed in users) so that they can upload a thumbnail at a later time. In order to do so, I'm picking up the "user" object from the currentlysignedin user to be able to for instance use the updateProfile function. ie:
// within the v9 code example
const { user } = useAuthContext()
//=======================================
// in the useAuthContext File:
import { AuthContext } from "../CONTEXT/AuthContext.js"
import { useContext } from "react"
export const useAuthContext = () => {
const context = useContext(AuthContext)
return context
}
//=======================================
// in the authContext File:
import { createContext, useReducer, useEffect } from 'react'
import { onAuthStateChanged } from 'firebase/auth'
import { auth } from '../Firebase/config'
export const AuthContext = createContext()
export const authReducer = (state, action) => {
switch (action.type) {
case 'LOGIN':
return { ...state, user: action.payload }
case 'LOGOUT':
return { ...state, user: null }
case 'AUTH_IS_READY':
return { user: action.payload, authIsReady: true }
default:
return state
}
}
export const AuthContextProvider = ({ children }) => {
const [state, dispatch] = useReducer(authReducer, {
user: null,
authIsReady: false
})
useEffect(() => {
const unsub = onAuthStateChanged(auth, user => {
dispatch({ type: 'AUTH_IS_READY', payload: user })
unsub()
})
}, [])
// console.log('AuthContext state:', state)
return (
<AuthContext.Provider value={{ ...state, dispatch }}>
{ children }
</AuthContext.Provider>
)
}
CodePudding user response:
In the V9 code snippet, you are trying to get the download URL before even uploading the image at first place. Also if you don't need to track update progress, use uploadBytes()
instead:
import { ref, getDownloadURL, uploadBytesResumable } from 'firebase/storage'
import { updateProfile } from 'firebase/auth'
// pass the path in ref to create a StorageReference
const storageRef = ref(storage, `thumbnails/${res.user.uid}/${thumbnail.name}`)
// upload image, file is a blob here
await uploadBytes(storageRef, file);
const downloadUrl = await getDownloadURL(storageRef);
// this function returns promise too, add await
await updateProfile(user, { photoURL: downloadUrl })