https://supabase.com/docs/guides/realtime/presence
Pressence 는 채널에 config를 넣어줘야함 (아래 예시와 같이)
import { createClient } from '@supabase/supabase-js'
const channelC = supabase.channel('test', {
config: {
presence: {
key: 'userId-123',
},
},
})
const supabase = createBrowserSupabaseClient();
useEffect(() => {
const channel = supabase.channel("online_users", {
config: {
presence: {
key: loggedInUser.id,
},
},
});
//presence -> 온라인 유저를 파악하기 위해 좋은 api
channel.on("presence", { event: "sync" }, () => {
const newState = channel.presenceState();
console.log(newState);
});
channel.subscribe(async (status) => {
if (status !== "SUBSCRIBED") {
return;
}
const newPresencesStatus = await channel.track({
onlineAt: new Date().toISOString(),
});
console.log(newPresencesStatus);
});
콘솔을 확인해보면 OK가 뜬다.
atom 에 새로운 상태 정의
export const presenceState = atom({
key: "presenceState",
default: null,
});
const [presence, setPresence] = useRecoilState(presenceState);
useEffect(() => {
const channel = supabase.channel("online_users", {
config: {
presence: {
key: loggedInUser.id,
},
},
});
//presence -> 온라인 유저를 파악하기 위해 좋은 api
channel.on("presence", { event: "sync" }, () => {
const newState = channel.presenceState();
const newStateObj = JSON.parse(JSON.stringify(newState));
//useRecoilState로 전역 상태 저장
//newState를 그대로 썼을 때 그 데이터를 바꿔버릴 수 있기 때문에
//깔끔하게 object만들어서 사용한다.
setPresence(newStateObj);
});
channel.subscribe(async (status) => {
if (status !== "SUBSCRIBED") {
return;
}
const newPresencesStatus = await channel.track({
onlineAt: new Date().toISOString(),
});
console.log(newPresencesStatus);
});
return () => {
channel.unsubscribe();
};
}, []);
onlineAt 을 수정한다.
{getAllUsersQuery.data?.map((user, index) => (
<Person
key={index}
onclick={() => {
setSelectedUserId(user.id);
setSelectedUserIndex(index);
}}
index={index}
isActive={selectedUserId === user.id}
name={user.email.split("@")[0]}
onChatScreen={false}
onlineAt={presence?.[user.id]?.[0]?.onlineAt}
userId={user.id}
/>
))}
Person 컴포넌트에서도 마지막 접속시간 표시되는 부분에
onlineAt이 있을 경우에만 출력되게 코드를 수정한다.
<div>
<p className="text-black font-bold text-xl">{name}</p>
<p className="text-gray-500 text-sm">
{onlineAt && timeAgo.format(Date.parse(onlineAt))}
</p>
</div>
'FRONTEND > Next.js' 카테고리의 다른 글
NEXT.JS 의 프리페칭(pre-fetching)의 동작 (1) | 2024.12.08 |
---|---|
사전 렌더링 이해하기 (0) | 2024.11.28 |
[Next.js 14 + Supabase ] Supabase realtime (2) - 실시간 채팅 구현 (0) | 2024.08.19 |
[Next.js 14 + Supabase ] Supabase realtime (1) (0) | 2024.08.18 |
[Next.js 14 ] StrictMode 해제 하는 방법 (0) | 2024.08.17 |