Written by
Lee Jongseo
on
on
Firebase - online상태 나타내기(7)
online, offline 상태 나타내기
유저가 온라인 상태인지 오프라인 상태인지 나타내기 위해서는 User의 connection 상태를 알 수 있어야 한다.
Offline
Online
Connection state
firebase의 database는 유저가 online상태면 .info/connected
라는 특수한 ref
에 value
를 추가한다. 이를 코드로 표현하면 다음과 같다.
const connectionRef = firebase.database().ref(".info/connected");
connectionRef.on("value", (snap) => {
if (snap.val()) {
// online
// 유저 온라인 상태 저장
} else {
// offline
}
});
presence 저장하기
유저의 connection상태를 저장해야 해당 데이터를 가져와 화면에 connection상태를 보여줄 수 있을 것이다. 따라서 connection상태를 저장하는 presence
collection을 구성한다.
const presenceRef = firebase.database().ref("presence");
유저의 커넥션 상태가 online인 경우, presence에 해당 유저의 키를 저장한다. 그리고 offline상태면 유저의 키를 삭제한다.
// 컴포넌트가 마운트하면 presence에 유저의 커넥션 상태가 저장된다.
useEffect(() => {
connectionRef.on("value", (snap) => {
if (snap.val()) {
// presence 밑에 현재 유저 아이디 ref를 형성한다.
const ref = presenceRef.child(currentUser.id);
ref.set(true); // online 상태 => true
// Disconnect시, 데이터를 remove 한다.
ref.onDisconnect().remove((err) => {
if (err) {
// remove error
console.error(err);
}
});
} else {
// offline
}
});
}, []);
로그인 이전
로그인 이후 presence에 값이 추가되는 것을 볼 수 있다.
커넥션 상태 화면에 표현하기
presence 가져오기
presenceRef
를 통해서 값을 가져올 수 있다.
const [presenceList, setPresenceList] = useState([]);
useEffect(() => {
let loaded = [];
presenceRef.on("child_added", (snap) => {
if (currentUser.id !== snap.key) {
loaded.push(snap.key); // 다른 유저의 키가 담기게 된다.
setPresenceList([...loaded]);
}
});
presenceRef.on("child_remvoved", (snap) => {
let loaded = [];
if (currentUser.id !== snap.key) {
loaded.push(snap.key); // 다른 유저의 키가 담기게 된다.
setPresenceList([...loaded]);
}
});
}, []);
이제 activeUsers
에는 현재 접속해 있는 유저의 키가 담기게 된다. 이제 이 키를 이용하여 어떤 유저가 접속해있는지 화면에 표시할 수 있다.
presence 표현하기
데이터베이스에서 users
를 가져온 다음에 user에 status
라는 새로운 프로퍼티를 만들고 presence에 따라서 online 또는 offline 값을 부여해준다.
const [users, setUsers] = useState([]);
const usersRef = firebase.database().ref("users");
useEffect(() => {
let loaded = [];
usersRef.child("child_added", (snap) => {
if (currentUser.id !== snap.key) {
let user = snap.val();
user["id"] = snap.key;
if (presenceList && presenceList.includes(user.id)) {
user["status"] = "online";
} else {
user["status"] = "offline";
}
loaded.push(user);
setUsers([...loaded]);
}
});
}, []);
// user.status로 connection상태를 조회할 수 있다.
JSX코드에서 다음과 같이 스타일링할 수 있다.
{
users.map((user) => (
<Menu.Item>
{user.name}
<Icon name="circle" color={user.status === "online" ? `green` : "red"} />
</Menu.Item>
));
}