I am now following this youtube video to develop an Instagram clone app by using React with firebase.
The error occurred at the point below, on the video at 2:36:29.
It says "Syntax error: Unexpected token (93:12)"
{user?.displayName ? (
<ImageUpload username={user.displayName} />
) : (
<h3>sorry you need to login to upload</h3>
)}
what I tried
・Just put <ImageUpload username={user.displayName} />
=> I got 「firebase is not defined」 error on the other js file.
・put "user.displayName"
instead of "user?.displayName"
(? is erased)
=> more complicated error occur that "TypeError: Cannot read properties of null (reading 'displayName')"
・Put {user ? (<ImageUpload username={user.displayName} />) : (<h3>Sorry you need to login !!</h3>)}
eraced displayName
=> only visual works(surely, the username is not given in this case)
Adobe three tries, I guess displayName is the main point to solve the issue...
If you are good at React.js or you have seen the same error, please give me advice.
Whole App.js codes↓
App.js
import React, { useState, useEffect } from 'react'
import './App.css';
import Post from './Post';
import { db, auth } from './firebase';
import Modal from '@mui/material/Modal';
import Box from '@mui/material/Box';
import Button from '@mui/material/Button';
import Input from '@mui/material/Input';
//import Typography from '@mui/material/Typography';
import ImageUpload from './ImageUpload';
const style = {
position: 'absolute',
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)',
width: 400,
bgcolor: 'background.paper',
border: '2px solid #000',
boxShadow: 24,
p: 4,
};
function App() {
const [posts, setPosts] = useState([]);
const [open, setOpen] = React.useState(false);
const [openSignIn, setOpenSignIn] = useState(false);
const handleOpen = () => setOpen(true);
const handleClose = () => setOpen(false);
const [username, setUsername] = useState('');
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [user, setUser] = useState(null);
useEffect(() => {
const unsubscribe = auth.onAuthStateChanged((authUser) => {
if (authUser) {
//User has logged IN
console.log(authUser);
setUser(authUser);
//↑ is keep user logged in after refresh
} else {
//User has logged OUT
setUser(null);
}
})
return () => {
//perform some cleanup actions
unsubscribe(null);
}
}, [user, username]);
//useEffect => where the code runs, last []) means the code runs only once
useEffect(() => {
db.collection('posts').onSnapshot(snapshot => {
setPosts(snapshot.docs.map(doc => ({
id: doc.id,
post: doc.data()
})));
})
}, []);
//signup func
const signup = (event) => {
event.preventDefault();
auth
.createUserWithEmailAndPassword(email, password)
.then((authUser) => {
return authUser.user.updateProfile({
displayName: username
})
})
.catch((error) => alert(error.message));
setOpen(false);
}
//signin func
const signin = (event) => {
event.preventDefault();
auth
.signInWithEmailAndPassword(email, password)
.catch((error) => alert(error.message));
setOpenSignIn(false);
}
return (
<div className="app">
{user.displayName ? (
<ImageUpload username={user.displayName} />
) : (
<h3>sorry you need to login to upload</h3>
)}
<div className="app__header">
<img
className="app__headerImage"
src="https://www.instagram.com/static/images/web/mobile_nav_type_logo.png/735145cfe0a4.png"
alt="HeaderImage"
/>
{user ? (
<Button onClick={() => auth.signOut()}>Logout</Button>
) : (
<div className="app__loginContainer">
<Button onClick={() => setOpenSignIn(true)}>SignIn</Button>
<Button onClick={() => setOpen(true)}>SignUp</Button>
</div>
)}
</div>
<Modal
open={open}
onClose={() => setOpen(false)}
>
<Box sx={style}>
<form className="app__signup">
<center>
<img
className="app__headerImage"
src="https://www.instagram.com/static/images/web/mobile_nav_type_logo.png/735145cfe0a4.png"
alt="HeaderImage"
/>
</center>
<Input
type="text"
placeholder="username"
//at first, ↓ was value={username}, but typing cannot be shown on the screen in that case,
//https://stackoverflow.com/questions/34006333/cant-type-in-react-input-text-field
//↑is the trouble shooting, which says try defaultValue instead of value(V is capital).
defaultValue={username}
onChange={(e) => setUsername(e.target.value)}
/>
<Input
type="text"
placeholder="email"
defaultValue={email}
onChange={(e) => setEmail(e.target.value)}
/>
<Input
type="text"
placeholder="password"
defaultValue={password}
onChange={(e) => setPassword(e.target.value)}
/>
<center>
<Button type="submit" onClick={signup}>SignUp</Button>
</center>
</form>
</Box>
</Modal>
<Modal
//signupModal
open={openSignIn}
onClose={() => setOpenSignIn(false)}
>
<Box sx={style}>
<form className="app__signup">
<center>
<img
className="app__headerImage"
src="https://www.instagram.com/static/images/web/mobile_nav_type_logo.png/735145cfe0a4.png"
alt="HeaderImage"
/>
</center>
<Input
type="text"
placeholder="email"
defaultValue={email}
onChange={(e) => setEmail(e.target.value)}
/>
<Input
type="text"
placeholder="password"
defaultValue={password}
onChange={(e) => setPassword(e.target.value)}
/>
<center>
<Button type="submit" onClick={signin}>SignIn</Button>
</center>
</form>
</Box>
</Modal>
<h1>TEST</h1>
{/* header */}
{
posts.map(({ id, post }) => (
<Post username={post.username} caption={post.caption} imageUrl={post.imageUrl} />
))
}
{/* post */}
{/* post */}
</div >
);
}
export default App;
Here↓ is ImageUpload.js which I got firebase is not defined when I erase the? mark from ImageUpload tag,,,,
firebase is not defined from this line↓
timestamp: firebase.firestore.FieldValue.serverTimestamp(),
ImageUpload.js
import React, { useState } from 'react';
import Button from '@mui/material/Button';
import { storage, db } from "./firebase";
import firebase from 'firebase/app';
function ImageUpload(username) {
const [image, setImage] = useState(null);
const [url, setUrl] = useState("");
const [progress, setProgress] = useState(0);
const [caption, setCaption] = useState('');
const handleChange = (e) => {
if (e.target.files[0]) {
setImage(e.target.files[0])
}
};
const handleUpload = () => {
const uploadTask = storage.ref('images/${image.name}').put(image);
uploadTask.on(
"state_change",
(snapshot) => {
//progress function
const progress = Math.round(
(snapshot.bytesTransferred / snapshot.totalBytes) * 100
);
setProgress(progress);
},
(error) => {
//error function
console.log(error);
alert(error.message);
},
() => {
//complete func
storage
.ref("images")
.child(image.name)
.getDownloadURL()
.then(url => {
//post image inside DB
db.collection("posts").add({
timestamp: firebase.firestore.FieldValue.serverTimestamp(),
caption: caption,
imageUrl: url,
username: username
});
setProgress(0);
setCaption("");
setImage(null);
})
}
)
}
return (
<div>
{/* I want to have .... */}
{/* caption input */}
{/* file picker */}
{/* Post button */}
<progress value={progress} max="100" />
<input type="text" placeholder="enter a caption.." onChange={event => setCaption(event.target.value)} />
<input type="file" onChange={handleChange} />
<Button onClick={handleUpload}>
upload
</Button>
</div >
)
}
export default ImageUpload
To be safe here ↓ is firebase.js(privacy info are shown as ***)
firebase.js
import firebase from "firebase";
const firebaseApp = firebase.initializeApp({
apiKey: "***",
authDomain: "***.firebaseapp.com",
projectId: "***",
storageBucket: "***.appspot.com",
messagingSenderId: "*****",
appId: "****",
measurementId: "****"
})
const db = firebase.firestore();
const auth = firebase.auth();
const storage = firebase.storage();
export { db, auth, storage };
And index.js
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
reportWebVitals();
Moreover, firebase version is 8.10.0, using MacBook air intel one OS BigSur