การแสดงสถานะ 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)