英文:
Getting a browser notification from anybody but the current auth. user
问题
// Chat.js中的代码
import { useEffect, useState } from "react";
import { addDoc, collection, serverTimestamp, onSnapshot, query, where, orderBy } from "firebase/firestore";
import { auth, db } from "../firebase-config";
import "../styles/Chat.css";
import IDLogo from "../images/IDLogo.png";
import notificationSound from "../sounds/message_sound.mp3";
import addNotification from "react-push-notification";
import DefaultProfilePicture from "../images/default_pfp.jpeg";
export const Chat = props => {
const { room } = props;
const [newMessage, setNewMessage] = useState();
const [messages, setMessages] = useState([]);
const messagesRef = collection(db, "messages");
useEffect(() => {
const queryMessages = query(messagesRef, where("room", "==", room), orderBy("createdAt"));
const unsubscribe = onSnapshot(queryMessages, snapshot => {
let messages = [];
snapshot.forEach(doc => {
messages.push({ ...doc.data(), id: doc.id });
});
setMessages(messages);
});
return () => unsubscribe();
}, []);
useEffect(() => {
const messagesContainer = messagesRef.current;
messagesContainer.scrollTop = messagesContainer.scrollHeight;
}, [messagesRef]);
const handleSubmit = async e => {
e.preventDefault();
if (newMessage === "") return;
const currentUser = auth.currentUser;
await addDoc(messagesRef, {
text: newMessage,
createdAt: serverTimestamp(),
user: currentUser.displayName,
profilePicture: currentUser.photoURL,
room,
});
if (newMessage && newMessage.user !== auth.currentUser.displayName) {
addNotification({
title: "New Message",
message: newMessage.text,
duration: 5000,
native: true,
icon: IDLogo,
});
}
setNewMessage("");
};
useEffect(() => {
const audio = new Audio(notificationSound);
const lastMessage = messages[messages.length - 1];
if (lastMessage && lastMessage.user !== auth.currentUser.displayName) {
audio.play();
}
}, [messages]);
return (
<div className='chat'>
<div className='header'>
<h1>
Welcome to: <span className='Chat__room--title'>{room.toUpperCase()}</span>
</h1>
</div>
<div ref={messagesRef} className='messages'>
{messages.map(message => (
<p className='Chat__message'>
{message.profilePicture ? (
<img className='profile__picture' referrerpolicy='no-referrer' src={message.profilePicture} alt={message.user} />
) : (
<img className='profile__picture' src={DefaultProfilePicture} alt={message.user}></img>
)}
{message.user} : {message.text}
</p>
))}
</div>
<div className='send__message__container'>
<form onSubmit={handleSubmit} className='new__message__form'>
<input
spellCheck='false'
onChange={e => setNewMessage(e.target.value)}
className='new__message__input'
placeholder='Type a message here...'
value={newMessage}
/>
<button type='submit' className='signOut--sendMessage__button'>
Send
</button>
</form>
</div>
</div>
);
};
英文:
I'm currently building a chat app in React JS and I've been going crazy for the past two days with this issue. I want to make it so whenever there is a new message, a browser notification appears.
The issue is that I only get a notification when I send a message, not when anybody else sends a message. It's supposed to be literally the other way around.
I'm using the react-push-notification npm package to implement this.
Chat.js:
import { useEffect, useState } from "react";
import { addDoc, collection, serverTimestamp, onSnapshot, query, where, orderBy } from "firebase/firestore";
import { auth, db } from "../firebase-config";
import "../styles/Chat.css";
import IDLogo from "../images/IDLogo.png";
import notificationSound from "../sounds/message_sound.mp3";
import addNotification from "react-push-notification";
import DefaultProfilePicture from "../images/default_pfp.jpeg";
export const Chat = props => {
const { room } = props;
const [newMessage, setNewMessage] = useState();
const [messages, setMessages] = useState([]);
const messagesRef = collection(db, "messages");
useEffect(() => {
const queryMessages = query(messagesRef, where("room", "==", room), orderBy("createdAt"));
const unsubscribe = onSnapshot(queryMessages, snapshot => {
let messages = [];
snapshot.forEach(doc => {
messages.push({ ...doc.data(), id: doc.id });
});
setMessages(messages);
});
return () => unsubscribe();
}, []);
useEffect(() => {
const messagesContainer = messagesRef.current;
messagesContainer.scrollTop = messagesContainer.scrollHeight;
}, [messagesRef]);
const handleSubmit = async e => {
e.preventDefault();
if (newMessage === "") return;
const currentUser = auth.currentUser;
await addDoc(messagesRef, {
text: newMessage,
createdAt: serverTimestamp(),
user: currentUser.displayName,
profilePicture: currentUser.photoURL,
room,
});
if (newMessage && newMessage.user !== auth.currentUser.displayName) {
addNotification({
title: "New Message",
message: newMessage.text,
duration: 5000,
native: true,
icon: IDLogo,
});
}
setNewMessage("");
};
useEffect(() => {
const audio = new Audio(notificationSound);
const lastMessage = messages[messages.length - 1];
if (lastMessage && lastMessage.user !== auth.currentUser.displayName) {
audio.play();
}
}, [messages]);
return (
<div className='chat'>
<div className='header'>
<h1>
Welcome to: <span className='Chat__room--title'>{room.toUpperCase()}</span>
</h1>
</div>
<div ref={messagesRef} className='messages'>
{messages.map(message => (
<p className='Chat__message'>
{message.profilePicture ? (
<img className='profile__picture' referrerpolicy='no-referrer' src={message.profilePicture} alt={message.user} />
) : (
<img className='profile__picture' src={DefaultProfilePicture} alt={message.user}></img>
)}
{message.user} : {message.text}
</p>
))}
</div>
<div className='send__message__container'>
<form onSubmit={handleSubmit} className='new__message__form'>
<input
spellCheck='false'
onChange={e => setNewMessage(e.target.value)}
className='new__message__input'
placeholder='Type a message here...'
value={newMessage}
/>
<button type='submit' className='signOut--sendMessage__button'>
Send
</button>
</form>
</div>
</div>
);
};
答案1
得分: 1
Just move your add notification function out of handle submit function :
如果 (newMessage && newMessage.user !== auth.currentUser.displayName) {
添加通知({
标题: "新消息",
消息: newMessage.text,
持续时间: 5000,
原生: true,
图标: IDLogo,
});
}
Take it to the next useEffect :
将其移到下一个 useEffect 中:
useEffect(() => {
const audio = new Audio(notificationSound);
const lastMessage = messages[messages.length - 1];
if (lastMessage && lastMessage.user !== auth.currentUser.displayName) {
audio.play();
添加通知({
标题: "新消息",
消息: newMessage.text,
持续时间: 5000,
原生: true,
图标: IDLogo,
});
}
}, [messages]);
英文:
Just move your add notification function out of handle submit function :
if (newMessage && newMessage.user !== auth.currentUser.displayName) {
addNotification({
title: "New Message",
message: newMessage.text,
duration: 5000,
native: true,
icon: IDLogo,
});
}
Take it to the next useEffect :
useEffect(() => {
const audio = new Audio(notificationSound);
const lastMessage = messages[messages.length - 1];
if (lastMessage && lastMessage.user !== auth.currentUser.displayName) {
audio.play();
addNotification({
title: "New Message",
message: newMessage.text,
duration: 5000,
native: true,
icon: IDLogo,
});
}}, [messages]);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论