祝大家一切顺利。我在react中使用fireship io教程来构建聊天应用程序。我更新了如何使用钩子获取数据,而不是如何在视频中完成。
问题是,我有它的工作,我可以发送和接收消息,但我不能应用适当的CSS样式取决于哪个用户发送消息。奇怪的是,我能够将文本和uid作为道具进行控制台日志。
重点是const ChatMessage,根据当前用户的uid,它将更改CSS样式以模仿imessage的样式。下面是一个例子。
最终产品
我把它设置在我从vs code运行npm的地方,我从我的两个谷歌账户访问应用程序。一个来自firefox,一个来自chrome。
我真的很想掌握firebase和hook的反应,任何有帮助的东西。
欢呼,
教程源代码: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;
}
我已经试过了。调用了currentUser。我还将函数从函数格式重新格式化为const格式,但我不认为这有多大区别。
似乎在您的ChatMessage
组件中,messageClass
将获得基于props.uid
是否等于当前用户的uid
的值。
如果这是目标,您可以这样设置:
const messageClass = props.uid === auth.currentUser?.uid ? "sent" : "recieved";
代替:
const messageClass = props.uid === auth.currentUser ? "sent" : "recieved";
因为auth.currentUser
是具有一些用户数据属性的对象,如uid
。