我目前正在用 React JS 建立一個聊天應用程序,過去兩天我一直為這個問題而瘋狂。我想做到這一點,以便每當有新訊息時,就會出現瀏覽器通知。
問題是我只有在發送訊息時才會收到通知,而在其他人發送訊息時則不會收到通知。實際情況應該是相反的。
我正在使用react-push-notification npm 套件來實現這一點。
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> ); };
P粉1954022922024-04-05 11:09:28
只需將新增通知功能移出處理提交功能即可:
if (newMessage && newMessage.user !== auth.currentUser.displayName) { addNotification({ title: "New Message", message: newMessage.text, duration: 5000, native: true, icon: IDLogo, }); }
將其帶到下一個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]);