ระบบ E-commerce แบบกำหนดเองบน Firebase

ผมสร้างเว็บไซต์ E-commerce แบบกำหนดเองขึ้นมาใหม่ทั้งหมด โดยไม่ได้ใช้แพลตฟอร์มสำเร็จรูป แต่เลือกใช้ Firebase Realtime Database และ Netlify แทน

ลูกค้าต้องการการตั้งค่าที่เฉพาะเจาะจง พวกเขาต้องการแคตตาล็อกสินค้าที่มีตัวเลือกราคาที่หลากหลายและแผงควบคุมสำหรับผู้ดูแลระบบ (admin panel) นอกจากนี้ ทีมขายยังจำเป็นต้องสามารถสั่งซื้อสินค้าผ่านเว็บไซต์ได้โดยตรงอีกด้วย

และนี่คือวิธีที่ผมใช้แก้ปัญหาทางเทคนิคที่สำคัญต่างๆ

การแยกข้อมูล ผมแยกฐานข้อมูล E-commerce ออกจากฐานข้อมูลการจัดการภายใน เพื่อป้องกันไม่ให้ข้อมูลทางการค้าไปปะปนกับไฟล์ที่มีความสำคัญ เช่น เงินเดือนพนักงานหรือข้อมูลด้านงบประมาณ

การทำ Data Modeling สำหรับการกำหนดราคา แผนการกำหนดราคามักจะซ้ำกันในสินค้าหลายๆ ชิ้น หากคุณคัดลอกข้อมูลแผนราคาไว้ในสินค้าทุกชิ้น การอัปเดตข้อมูลจะกลายเป็นเรื่องที่ยุ่งยากมาก

  • ผมสร้างคลังข้อมูลกลาง (global archive) สำหรับแผนราคาทั้งหมด
  • สินค้าแต่ละชิ้นจะเก็บเพียง array ของ plan IDs เท่านั้น
  • วิธีนี้ช่วยให้การอัปเดตทำได้อย่างรวดเร็วและป้องกันข้อผิดพลาดของข้อมูล

การรันเลขที่คำสั่งซื้อแบบ Atomic เมื่อมีผู้ใช้งานหลายคนสั่งซื้อสินค้าพร้อมกัน คุณจะเจอกับปัญหา race condition หากผู้ใช้สองคนอ่านเลขที่คำสั่งซื้อล่าสุดเป็นเลขเดียวกัน คำสั่งซื้อหนึ่งจะถูกเขียนทับ

  • ผมใช้ Firebase transactions ในการแก้ปัญหานี้
  • ฟังก์ชัน runTransaction ช่วยให้มั่นใจว่าตัวเลขจะเพิ่มขึ้นอย่างถูกต้อง แม้จะมีผู้ใช้งานจำนวนมากเข้ามาพร้อมกันก็ตาม
  • สิ่งนี้ช่วยรับประกันว่าทุกคำสั่งซื้อจะมีเลขที่เฉพาะตัวไม่ซ้ำกัน

การเข้าถึงระบบ Admin อย่างปลอดภัย ผมไม่ต้องการเก็บรหัสผ่านไว้ในซอร์สโค้ด และหลีกเลี่ยงการใช้การแฮชแบบง่ายๆ อย่าง MD5

  • ผมใช้ PBKDF2 ผ่าน Web Crypto API
  • วิธีนี้จะทำการแฮชซ้ำหลายพันครั้ง (iterations)
  • ทำให้การโจมตีแบบ brute-force มีต้นทุนที่สูงเกินกว่าที่แฮกเกอร์จะทำได้
  • ผมจะเก็บเพียงค่า salt และ hash ไว้ในโค้ดเท่านั้น

การแก้ไขบั๊ก 'เลขศูนย์' ผมพบข้อผิดพลาดที่สินค้าซึ่งมีราคาเป็น 0 แสดงผลเป็น "price to be defined"

  • สาเหตุเกิดจาก JavaScript มองว่า 0 เป็นค่า "falsy"
  • ผมแก้ไขปัญหานี้ด้วยการเปลี่ยนตรรกะ (logic)
  • แทนที่จะใช้ "price || null" ผมเปลี่ยนไปใช้ "price != null" แทน
  • วิธีนี้ช่วยให้ระบบรับรู้ว่า 0 คือตัวเลขที่ถูกต้อง

การตั้งค่า CSP Firebase ใช้ subdomain แบบไดนามิก ซึ่งแท็ก HTML meta มาตรฐานสำหรับ Content Security Policy (CSP) ไม่สามารถรองรับ wildcard เหล่านี้ได้

  • ผมจึงย้ายการตั้งค่า CSP จาก HTML ไปไว้ที่ Netlify HTTP headers แทน
  • วิธีนี้ช่วยให้ผมสามารถใช้ wildcard เพื่อให้บริการต่างๆ ของ Firebase ทำงานได้อย่างถูกต้อง

การสร้างระบบแบบกำหนดเองต้องใช้มากกว่าแค่การเขียนโค้ด แต่มันต้องอาศัยการตัดสินใจด้านสถาปัตยกรรม (architectural choices) เพื่อป้องกันความล้มเหลวเมื่อระบบใช้งานจริง (production)

Source: https://dev.to/androve2k/custom-e-commerce-on-firebase-catalog-atomic-orders-and-admin-panel-42ec