burakorkmez / mern-chat-app Goto Github PK
View Code? Open in Web Editor NEWReal Time Chat App | MERN && Socket.io && JWT
License: MIT License
Real Time Chat App | MERN && Socket.io && JWT
License: MIT License
Error in send Message Route TypeError: getReceiverSocketId is not a function
const Conversation = require("../models/conversation.models");
const Message = require("../models/message.models");
const { io } = require("../app");
const getReceiverSocketId = require("../app").getReceiverSocketId;
const sendMessage = async(req,res)=>{
// console.log("messages",req.params.id);
try {
const {message} = req.body;
const receiverId = req.params.id;
const senderId = req.user._id;
console.log(`Sender: ${senderId}, Receiver: ${receiverId},, Message" ${message}`);
let conversation = await Conversation.findOne({
participants: { $all : [senderId, receiverId]}
})
//send 1st time
if(!conversation){
conversation = await Conversation.create({
participants: [senderId,receiverId],
})
}
const newMessage = new Message({
senderId,
receiverId,
message
})
if(newMessage){
conversation.messages.push(newMessage._id);
}
// await conversation.save();
// await newMessage.save();
//optimize the upper 2 line
await Promise.all([conversation.save(), newMessage.save()])//this will run in parallel
//Socket IO
const receiverSocketId = getReceiverSocketId(receiverId);
if (receiverSocketId) {
// io.to(<socket_id>).emit() used to send events to specific client
io.to(receiverSocketId).emit("newMessage", newMessage);
}
// console.log("newMessage", newMessage);
res.status(201).json(newMessage)
} catch (error) {
console.log("Error in send Message Route", error);
res.status(500).send({
success:false,
message: error.message
})
}
}
const getMessage = async(req,res)=>{
try {
const userToChatId = req.params.id;
const senderId = req.user._id;
const conversation = await Conversation .findOne({
participants:{$all : [senderId,userToChatId]},
}).populate("messages")//not ref but actual message
if(!conversation){
return res.status(200).send({
success:true,
message: [],
})
}
const messages = conversation.messages
res.status(200).send({
success:true,
message: messages
})
} catch (error) {
console.log("Error in Get Message Route", error);
res.status(500).send({
success:false,
message: error.message
})
}
}
module.exports = {sendMessage,getMessage}
When I sign up as a new user the browser shows the alert message " Unexpected token '<', "<!DOCTYPE "... is not valid JSON"
I hope this message finds you well. I wanted to express my heartfelt appreciation for your JavaScript chatApp. It has been an invaluable tool for my website, and I am deeply grateful for your hard work and dedication in creating such a useful application.
I am currently in the process of embedding the chat app into my webpage using an <iframe>, but I have encountered some difficulties and errors along the way. I have attached a screenshot of the error message I am receiving for your reference. Could you please provide me with the necessary steps or guidance to successfully embed the chat app on my webpage.
Thank you once again for your amazing work, and I truly appreciate your assistance in helping me resolve this issue
solved
This behaviour results in incorrect message placement and potential confusion for users involved.
in real time chat we set our message context with updated message and set it . but actually its not tru because if reciver selected conversation is diffrent then also he find your mesdsage but it should not let's take and example
if there is thee user jhon , bob and alice now jhon and bob doing chat (online) in this code if jhon send message to bob and if selected conversation of bob is alice then also it shows new upcoming message but bob and alice neve do chat new upcoming message is actully of jhon if we refresh it then it comes propely due to context refresh in this case .
to solve this :
we have to check if selected conversation id is same as reciver id then and then update message context otherwise dont update context of message.
`const useListenMessages = () => {
const { socket } = useSocketContext();
const { messages, setMessages, selectedConversation } = useConversation();
const { user } = useAutherContext();
useEffect(() => {
socket?.on("new-message", ( newMessage ) => {
const check = newMessage.receiverId == selectedConversation.id
console.log(selectedConversation);
newMessage.shake = true;
const sound = new Audio(notificationSound);
sound.play();
if (check) {
setMessages([...messages, newMessage]);
}
});
return () => {
socket?.off("new-message");
};
}, [socket, messages, setMessages]);
};
export default useListenMessages;`
It says no cookie found. Cookie is being created but my browser is ignoring it
Hello Everyone
I'm getting an empty array when trying to get online users .
My code is as follows :
// SocketContext.jsx :
import { createContext, useState, useEffect, useContext } from "react";
import { useAuthContext } from "./AuthContext";
import io from "socket.io-client";
const SocketContext = createContext();
export const useSocketContext = () => {
return useContext(SocketContext);
};
export const SocketContextProvider = ({ children }) => {
const [socket, setSocket] = useState(null);
const [onlineUsers, setOnlineUsers] = useState([]);
const { authUser } = useAuthContext();
useEffect(() => {
if (authUser) {
const socket = io("http://localhost:3000", {
query: {
userId: authUser._id,
},
});
setSocket(socket);
// socket.on() is used to listen to the events. can be used both on client and server side
socket.on("getOnlineUsers", (users) => {
setOnlineUsers(users);
});
return () => socket.close();
} else {
if (socket) {
socket.close();
setSocket(null);
}
}
}, [authUser]);
return (
<SocketContext.Provider value={{ socket, onlineUsers }}>
{children}
</SocketContext.Provider>
);
};
// conversation.jsx :
import { useSocketContext } from "../../context/SocketContext";
import useConversation from "../../zustand/useConversation";
function Conversation({ conversation, lastIdx, emoji }) {
const { selectedConversation, setSelectedConversation } = useConversation();
const isSelected = selectedConversation?._id === conversation._id;
const { onlineUsers } = useSocketContext();
console.log(onlineUsers);
const isOnline = onlineUsers.includes(conversation._id);
return (
<>
<div
className={`flex gap-2 items-center hover:bg-purple-900 rounded p-2 py-1 cursor-pointer
${isSelected ? "bg-purple-900" : ""}`}
onClick={() => setSelectedConversation(conversation)}
>
<div className={`avatar ${isOnline ? "online" : "offline"}`}>
<div className="w-12 rounded-full">
<img src={conversation.profilePicture} alt="user avatar" />
</div>
</div>
<div className="flex flex-col flex-1">
<div className="flex gap-3 justify-between">
<p className="font-bold text-gray-200">{conversation.fullName}</p>
<span className="text-xl">{emoji}</span>
</div>
</div>
</div>
{!lastIdx && <div className="divider my-0 py-0 h-1" />}
</>
);
}
export default Conversation;
I am getting an empty array as online users :
Array(0)
[]
Below is my server side code :
// socket.js
import { Server } from "socket.io";
import http from "http";
import express from "express";
const app = express();
const server = http.createServer(app);
const io = new Server(server, {
cors: {
origin: ["http://localhost:3000"],
methods: ["GET", "POST"],
},
});
export const getReceiverSocketId = (receiverId) => {
return userSocketMap[receiverId];
};
const userSocketMap = {}; // {userId: socketId}
io.on("connection", (socket) => {
console.log("a user connected", socket.id);
const userId = socket.handshake.query.userId;
if (userId != "undefined") userSocketMap[userId] = socket.id;
// io.emit() is used to send events to all the connected clients
io.emit("getOnlineUsers", Object.keys(userSocketMap));
// socket.on() is used to listen to the events. can be used both on client and server side
socket.on("disconnect", () => {
console.log("user disconnected", socket.id);
delete userSocketMap[userId];
io.emit("getOnlineUsers", Object.keys(userSocketMap));
});
});
export { app, io, server };
I tried reading socket.js documetation but i'm not able to find the error
Any help is appreciated!
In server.js, PORT is assigned prior to running dotenv.config(), which results in PORT always equating to 5000.
Hey @burakorkmez!
My sincere gratitude for the incredibly detailed and informative video tutorial you provided. Your clear explanations and step-by-step guidance made it much easier for me to understand the concepts and implement them effectively.
I was wondering if you could provide some guidance or tips on how to approach making an app mobile responsive. I tried to make it responsive but it isn't working as expected. I'm aware, you must be busy , but I would greatly appreciate it if you could please help me in any possible capacity to make the app responsive.
Just to be clear, login and signup page works perfectly fine on mobile as well however, actual problem arises when logged in and clicking on specific user to initiate the chat. I'm attaching the screenshots of the app when opened on mobile.
Once again, thank you so much for your invaluable contribution to the community through your tutorial. I truly appreciate your time and expertise.
Looking forward to your response.
Warm regards,
Amol
First of all thank you for this app, I followed through and learned a lot about developing chat app.
There's an issue I'd like to point out though, which resides in the useListenMessages
hook. The current implementation updates messages
whenever a new message comes in without checking the sender, meaning if I'm opening the conversation with A, then new messages from B will also update the chat window. The solution is to simply check if the sender matches the current conversation, and then update current messages accordingly.
Then again, it was a good run with your YT tutorial, thanks again.
whan i login i get this message [vite] http proxy error at /api/auth/signup: AggregateError [ECONNREFUSED]: at internalConnectMultiple (node:net:1116:18) at afterConnectMultiple (node:net:1683:7)
(i did just like you)
in the localhost it says Unexpected end of JSON input
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.