การแสดงสถานะ user online (หรือเรียกอีกอย่างว่า presence) คือการแสดงให้ admin เห็นว่า user A กำลัง online และใช้งาน app ของเราอยู่นะ และทันทีที่ user A ปิด browser หรือ logout ก็อัพเดทสถานะของ user A ทันทีว่า offline ซึ่งส่วนมากจะใช้ในระบบที่ต้องการเห็นสถานะ online/offline ของ user เช่น chat หรือพวก กระดานสนทนา อย่างเช่น discord
โชคดีที่ Firebase สามารถทำ presence ได้ และมีตัวอย่างโค้ดให้ด้วย
ขอลอกมาให้ดูดังนี้
// ดึง uid มาใช้งาน
const uid = firebase.auth().currentUser.uid
// สร้าง RTDB object เอาไว้ใช้งาน
const RTDB = firebase.database().ref()
// node พิเศษ เอามาดูได้ว่า uid ปัจจุบัน connect กับ Firebase อยู่หรือปล่าว
const amOnline = RTDB.child('.info/connected')
// ให้ RTDB ชี้ไปที่ /presence/{uid}
const presenceRef = RTDB.child('presence').child(uid)
// ให้ RTDB ชี้ไปที่ /sessions
const sessionsRef = RTDB.child('sessions')
amOnline.on('value', snapShot => {
// ถ้ายังไม่ได้ connect กับ Firebase ก็ยังไม่ต้องทำอะไร
if (!snapShot.val()) return
// connect ได้แล้วสร้าง presence ได้เลย
presenceRef.set(true)
// ถ้า disconnect เมื่อไหร่ก็ลบไปเลย
presenceRef.onDisconnect().remove()
// สร้าง session ขึ้นมาใหม่ โดยเก็บ uid และ startedAt
const session = sessionsRef.push({
startedAt: firebase.database.ServerValue.TIMESTAMP,
uid: uid,
})
// ในกรณีที่ disconnect ให้เพิ่ม endedAt ใน session ที่เพิ่งสร้างมาเมื่อกี้
session.child('endedAt')
.onDisconnect()
.set(firebase.database.ServerValue.TIMESTAMP)
})
จากโค้ดข้างบน
- เก็บข้อมูล session ของ user ไว้ใน
/sessions
โดยให้มี-
startedAt
= เวลาที่สร้าง session (ใช้firebase.database.ServerValue.TIMESTAMP
ก็เหมือนใช้NOW()
ใน MySQL) -
endedAt
= เวลาที่ปิด browser, ปิด tab -
uid
= uid ของ user
-
- เก็บข้อมูลสถานะ online/offline ที่
/presence
โดยจะใช้ key = uid - ทำ subscribe node พิเศษที่ชื่อว่า
.info/connected
ซึ่งจะเกิด value เมื่อ user connect กับ Firebase - เมื่อ connect ได้แล้วก็จะเอา uid ไปสร้าง
/sessions
และ/presence
- โดย session ให้ subscribe disconnect event ไว้ว่าถ้าปิด browser เมื่อไหร่ก็อัพเดทเพิ่ม
endedAt
ลงไป - และสำหรับ presence ก็ subscribe disconnect event ไว้ว่าถ้าปิด browser เมื่อไหร่ก็ลบตัวเองทันที
เวลาที่เปิด RTDB จะเห็นข้อมูลประมาณนี้ (สมมุติว่า uid = XXX)
https://app.firebaseio.com/
+- app
+- presence
+- XXX: true
+- sessions
+- M0m-2FnKgEok1UJRg
+- startedAt: 1582460581136
+- uid: XXX
ส่วนการเอาไปใช้งาน
แค่ให้ Firebase ดึงข้อมูลจาก RTDB/presence/{uid}
ถ้าหาเจอก็แสดงว่ากำลัง online อยู่
ยังไม่สมบูรณ์ มีอะไรต้องแก้อีกนะ
แต่สำหรับโค้ดตัวอย่างมีจุดอ่อนดังนี้
- กรณีที่ user reload page จะทำให้สถานะหยุด online แป๊ปนึง เพราะ Firebase จะโค้ดจะสร้าง session ใหม่
- กรณีที่ user เปิดหลาย tab และปิดไปสัก tab นึง จะทำให้สถานะกลายเป็น offline ทั้งๆที่เปิดบาง tab ค้างไว้
- กรณีที่ login หลาย device หรือหลาย browser ก็จะได้คล้ายๆกับข้อ 2.
ไว้รอบหน้าจะมาเล่าให้ฟังว่าแก้ไขอย่างไร :D
Note
- ดัดแปลงมาจาก Build Presence in Cloud Firestore
Top comments (0)