Issue
I hope you all are doing well. I was following this fireship io tutorial in building a chat app in react. I updated how I got the data with hooks instead of how it was done in the video.
The issue is, I have it working where I can send and receive messages, but I can't apply the appropriate CSS style depending on which user sent a message. The odd part is, I'm able to console log the text and the uid as props.
The focus is on const ChatMessage where, depending on the uid of the current user, it will change the CSS styling to mimic that of imessage. Here's an example.
Final Product
I have it set up where I run npm from vs code and I access the app from two of my google accounts. One from firefox, the other from chrome.
I'm really trying to get a hang of firebase react with hooks, anything helps.
Cheers,
Tutorial Source Code: https://github.com/fireship-io/react-firebase-chat
App.js
import "./App.css";
import "firebase/firestore";
import "firebase/auth";
import { useAuthState } from "react-firebase-hooks/auth";
import { db } from "./firebase";
import {
collection,
onSnapshot,
addDoc,
serverTimestamp,
query,
orderBy,
limit,
} from "firebase/firestore";
import { useEffect, useState, useRef } from "react";
import { getAuth, signInWithPopup, GoogleAuthProvider } from "firebase/auth";
const provider = new GoogleAuthProvider();
const auth = getAuth();
const userID = "";
function App() {
const [user] = useAuthState(auth);
return (
<div className="App">
<header>
<h1>SUp@ Ch@tZ🫡</h1>
<SignOut />
</header>
<section>{user ? <ChatRoom /> : <SignIn />}</section>
</div>
);
}
const ChatRoom = () => {
const [messages, setMessages] = useState([]);
const [formValue, setFormValue] = useState("");
const messagesRef = collection(db, "messages");
const recentMessage = useRef();
const queryAtts = query(messagesRef, orderBy("createdAt"), limit(25));
//Send Messages
const sendMessage = async (e) => {
e.preventDefault();
const { uid, photoURL } = auth.currentUser;
await addDoc(collection(db, "messages"), {
text: formValue,
createdAt: serverTimestamp(),
uid,
photoURL,
});
setFormValue("");
recentMessage.current.scrollIntoView({ behavior: "smooth" });
};
//Get Messages from Firestore
useEffect(() => {
//console.log(messagesRef);
onSnapshot(queryAtts, (snapshot) => {
setMessages(
snapshot.docs.map((doc) => {
return { id: doc.id, viewing: false, ...doc.data() };
})
);
});
}, []);
return (
<>
<main>
{messages &&
messages.map((msg, i) => (
<>
{console.log("Pre-Chat Msg uid: ", msg.uid)}
<ChatMessage
msg={msg.text}
uid={msg.uid}
photoURL={auth.currentUser.photoURL}
/>
</>
))}
<div ref={recentMessage}></div>
</main>
<form onSubmit={sendMessage}>
<input
value={formValue}
onChange={(e) => setFormValue(e.target.value)}
/>
<button type="submit" disabled={!formValue}>
😶🌫️
</button>
</form>
</>
);
};
const ChatMessage = (props) => {
//console.log("uid in chat msg: ", props.uid);
console.log("chat message photo: ", props.photoURL);
const messageClass = props.uid === auth.currentUser ? "sent" : "recieved";
console.log("useAuthStateHook uid: ", props.uid);
return (
<div className={`message ${messageClass}`}>
<img
src={
props.photoURL || "https://xsgames.co/randomusers/avatar.php?g=pixel"
}
alt={"broken lol"}
/>
<p key={props.uid}>{props.msg}</p>
</div>
);
};
const SignIn = () => {
const useSignInWithGoogle = () => {
signInWithPopup(auth, provider);
};
return (
<>
<button onClick={useSignInWithGoogle}>SignIn W/ Google</button>
<p>
Do not violate the community guidelines or you will be banned for life!
</p>
</>
);
};
const SignOut = () => {
return (
auth.currentUser && (
<button className="sign-out" onClick={() => auth.signOut()}>
Sign Out
</button>
)
);
};
export default App;
App.css
body {
background-color: #282c34;
}
.App {
text-align: center;
max-width: 728px;
margin: 0 auto;
}
.App header {
background-color: #181717;
height: 10vh;
min-height: 50px;
color: white;
position: fixed;
width: 100%;
max-width: 728px;
top: 0;
display: flex;
align-items: center;
justify-content: space-between;
z-index: 99;
padding: 10px;
box-sizing: border-box;
}
.App section {
display: flex;
flex-direction: column;
justify-content: center;
min-height: 100vh;
background-color: rgb(40, 37, 53);
}
main {
padding: 10px;
height: 80vh;
margin: 10vh 0 10vh;
overflow-y: scroll;
display: flex;
flex-direction: column;
}
main::-webkit-scrollbar {
width: 0.25rem;
}
main::-webkit-scrollbar-track {
background: #1e1e24;
}
main::-webkit-scrollbar-thumb {
background: #6649b8;
}
form {
height: 10vh;
position: fixed;
bottom: 0;
background-color: rgb(24, 23, 23);
width: 100%;
max-width: 728px;
display: flex;
font-size: 1.5rem;
}
form button {
width: 20%;
background-color: rgb(56, 56, 143);
}
input {
line-height: 1.5;
width: 100%;
font-size: 1.5rem;
background: rgb(58, 58, 58);
color: white;
outline: none;
border: none;
padding: 0 10px;
}
button {
background-color: #282c34; /* Green */
border: none;
color: white;
padding: 15px 32px;
text-align: center;
text-decoration: none;
display: inline-block;
cursor: pointer;
font-size: 1.25rem;
}
button:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.sign-in {
color: #282c34;
background: white;
max-width: 400px;
margin: 0 auto;
}
ul, li {
text-align: left;
list-style: none;
}
p {
max-width: 500px;
margin-bottom: 12px;
line-height: 24px;
padding: 10px 20px;
border-radius: 25px;
position: relative;
color: white;
text-align: center;
}
.message {
display: flex;
align-items: center;
}
.sent {
flex-direction: row-reverse;
}
.sent p {
color: white;
background: #0b93f6;
align-self: flex-end;
}
.received p {
background: #e5e5ea;
color: black;
}
img {
width: 40px;
height: 40px;
border-radius: 50%;
margin: 2px 5px;
}
I've tried maneuvering where the auth.currentUser was called. I also reformatted my functions from the function to const format, but I don't believe that makes much of a difference.
Solution
It seems that in your ChatMessage
component, the messageClass
will get a value based on if props.uid
equals to uid
of the current user.
If this is the goal, you can set it like:
const messageClass = props.uid === auth.currentUser?.uid ? "sent" : "recieved";
Instead of:
const messageClass = props.uid === auth.currentUser ? "sent" : "recieved";
Because auth.currentUser
is the object that has some user data properties such as uid
.
Answered By - John Li
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.