การสร้าง Notification Center ใน Firebase PWA
การบริหารจัดการทีมขายจำเป็นต้องใช้เครื่องมือมากมาย แผงควบคุมของผมใช้ทั้ง FCM push notifications, แชท, การแจ้งเตือน และปฏิทินที่ใช้ร่วมกัน
ปัญหาคือเครื่องมือเหล่านี้แยกกันอยู่คนละส่วน พนักงานต้องสลับไปมาหลายส่วนเพื่อตรวจสอบคำขอลาหยุดหรือข้อความ ไม่มีที่ใดที่เดียวที่สามารถดูทุกอย่างได้พร้อมกัน
ผมจึงสร้าง notification center ขึ้นมา ซึ่งเป็นไทม์ไลน์เดียวสำหรับทุกเหตุการณ์ที่เกี่ยวข้อง
วิธีที่ผมใช้ Firebase
ผมใช้ทั้ง Firestore และ Realtime Database (RTDB) โดยแต่ละอย่างมีวัตถุประสงค์การใช้งานที่เฉพาะเจาะจง
• Firestore สำหรับประวัติ: ใช้ .get() สำหรับข้อมูลที่ไม่มีการเปลี่ยนแปลง เช่น คำขอลาหยุด วิธีนี้จะช่วยควบคุมค่าใช้จ่ายให้ต่ำ เนื่องจากคุณไม่จำเป็นต้องใช้ listener ค้างไว้ตลอดเวลา
• RTDB สำหรับข้อมูลแบบเรียลไทม์: ใช้ .on('value') สำหรับแชท, การแจ้งเตือน และเหตุการณ์ในปฏิทิน โหนดเหล่านี้มีขนาดเล็กและต้องการการตอบสนองในทันที
การเลือกใช้ผิดประเภทจะส่งผลกระทบต่อค่าใช้จ่ายในบิล Firebase ของคุณทันที
อุปสรรคทางเทคนิค
การสร้าง UI จำเป็นต้องแก้ปัญหาหลัก 3 ประการ:
1. การใช้งานบนมือถือ (Mobile Usability)
ผมใช้ flex-wrap: wrap สำหรับ filter chips ในเวอร์ชันแรกผมใช้การเลื่อนในแนวนอน (horizontal scrolling) ซึ่งบนมือถือ ผู้ใช้มองไม่เห็น chips และไม่รู้ว่าสามารถเลื่อนได้ การปรับให้พวกมันเรียงกันเป็นสองแถวช่วยแก้ปัญหานี้ได้
2. การจัดตำแหน่ง CSS (CSS Positioning)
ผมทำการ append แผงควบคุมเข้ากับ document.body โดยตรง หากคุณนำ element ที่เป็น fixed ไปใส่ไว้ใน container ที่มี overflow:hidden การจัดตำแหน่งจะผิดเพี้ยนไป
3. บั๊กการกู้คืนเซสชัน (The Session Restore Bug)
ในระบบจริง ผู้ใช้ที่เลือก "remember me" จะเห็นแผงควบคุมว่างเปล่า เนื่องจากโค้ดเริ่มต้น (initialization code) จะทำงานเฉพาะตอนล็อกอินด้วยตัวเองเท่านั้น แต่จะไม่ทำงานเมื่อมีการกู้คืนเซสชัน (session restored)
ผมได้ใช้กลไก fallback 3 ระดับเพื่อให้แน่ใจว่า notification center จะโหลดขึ้นมาเสมอ:
- การใช้ wrapper ครอบฟังก์ชันการล็อกอิน
- การใช้ polling loop เพื่อตรวจสอบผู้ใช้ทุกๆ 500ms
- การใช้
MutationObserverเพื่อเฝ้าดูว่าโปรไฟล์ผู้ใช้ปรากฏขึ้นบนหน้าจอหรือไม่
ตัวอย่างการออกแบบที่ประสบความสำเร็จ
- ใช้
localStorageเพื่อติดตามสถานะการอ่านของผู้ใช้แต่ละคน - ใช้ composite indexes ใน Firestore สำหรับการคิวรีที่ซับซ้อน
- ใช้ media queries เพื่อย้าย element ที่เป็น
fixedบนมือถือ เพื่อไม่ให้ไปบังแถบด้านบน (top bar)
สถาปัตยกรรมเป็นเรื่องสำคัญ ใช้ Firestore สำหรับการเก็บ log และใช้ RTDB สำหรับการอัปเดตแบบเรียลไทม์
