เติมไฟอยู่ที่บ้านกับงาน Firebase Study Jam

Event Apr 5, 2020

ตื่นเต้นสุดๆกับการร่วมงาน Firebase Study Jam ที่บ้านจ้า ในวันอาทิตย์หน้าร้อน 5 เมษายน 2563 ในเวลาบ่ายโมงตรงถึงสามโมง เสร็จปุ๊ปดู Netfilx ต่อ เอ้ยย สรุปบล็อกสิ

ตื่นเต้นขนาดไหน รีบเปิดคอมแต่เช้าแล้วเข้าไปหน้ายูทูปที่สตรีมสดวันนี้หล่ะสิ555555 ซึ่งลิ้งที่สตรีมสดสามารถดูย้อนหลังได้เลยจ้าาา

https://www.youtube.com/watch?v=UKFulfiMR2Y

แน่นอนว่าในงานนี้ไม่มีใครเต้น เจนค่ะ! นุ่นคะ! โบค่ะ! เนอะ 55555555555555

งาน Firebase Study Jam เป็นงานที่จัดขึ้นหลายๆที่บนโลกในนี้ บางประเทศเขาจัดกันต้นปีเนอะ แล้วก็ทยอยๆกันจัดไป และในช่วงก็ COVID-19 ทำให้หลายๆคนต้อง Work From Home เลยเป็นครั้งแรกในไทยที่จัดแบบ online เลยจ้า เป็นการขึ้นเวทีพร้อมกันครั้งแรกของ Firebase GDE ทั้งสองท่าน คือ พี่ตี๋ และคุณนุ้ย โดยขึ้นเวทีพร้อมกันจากที่บ้าน โดยพี่ตี๋อยู่ที่สุราษ และคุณนุ้ยอยู่ที่พิษณุโลกจ้า

แน่นอนว่าบล็อกเราได้สแกนด้วยสายตาคร่าวๆเกี่ยวกับ Tech Stack ที่ใช้ในการสตรีมสดครั้งนี้ Firebase GDE ทั้งสองคน พูดคุยกันผ่าน Hangout Video Call มีการเตรียม Google Slide, link code lab และ Stackblitz, Firebase Console เพื่อแชร์หน้าจอให้พวกเราได้ทำตามกัน และทำการสตรีมสดผ่าน YouTube Live Streaming จ้า หลังจาก streaming เสร็จเราก็จะได้ดูต่อแบบย้อนหลังจ้า

สิ่งที่ทำในวันนี้ ก็คืออออ "Get to know Firebase for Web" เป็นการทำ Web Application ด้วย Firebase ซึ่งคนฟังอย่างเราไม่ต้องเตรียมอะไรมาเลยจ้า เตรียมแค่ใจ และสลับแท็ปให้ทันก็พอหล่ะ (ตอนแรกจะใช้ Sidecar แต่ดันหากันไม่เจอ งงเลยย แงงง) เพราะเราไม่ต้องลง tool หรือ editor ใดๆในวันนี้เลย เราจะทำผ่าน Stachblitz นั่นเอง เป็น online editor ที่เทพมากๆ แบบพิมพ์อะไรไปมันก็จะอัพเดต realtime ให้เราเลยจ้า แล้วก็เขียนเว็บก็จะใช้ HTML และ js จ้าาา เอ้า ลัลลั๊ลลา~ ลัลลัลลั๊ลลา~

แน่นอนว่าหลัง codelab มี surprise ด้วยหล่ะ และช่วงหลังจะมีการทำอาม่า เอ้ยยย AMA คือ Ask Me Anything ถามไรก็ถาม ไม่ต้องเกี่ยวกับ study jam วันนี้ก็ได้จ้า

มาเริ่มกันเถอะนะ

1) มาดูกันก่อน ว่าวันนี้จะได้อะไรกลับไป

ก่อนอื่น ไปที่ url ด้านบน ซึ่งเราจะเสกให้ในด้านล่างนี้ ชะแว้บบบบ

google.dev
Build a web app from scratch with Firebase and the StackBlitz online editor. You'll use basic HTML and JavaScript to talk to Firebase. This is a great introduction to using the Firebase console and integrating Firebase into an app. No extensive prior knowledge or software installations are neede…
https://google.dev/codelabs/firebase-get-to-know-web

สิ่งที่เราจะได้กลับไปในวันนี้ ก็คืออออ~~ หน้าเว็บ event ที่สามารถกด RSVP ได้ และมี guestbook ด้านล่างจ้า

RSVP มาจากภาษาฝรั่งเศษ ย่อมาจาก Répondez s'il vous plaît แปลเป็นภาษาอังกฤษว่า Please Response หรือในภาษาชาวบ้านคือ โปรดตอบเพื่อ confirm การเชิญในครั้งนี้ เพื่อให้เจ้าของงานนั้นเขาสามารถนับจำนวนคนในการเตรียมงานนั่นเอง
--https://en.wikipedia.org/wiki/RSVP

สิ่งที่จะได้กลับไปในวันนี้คือ

  • มีระบบ login เพื่อเข้าร่วมกิจกรรม ผ่าน Firebase Authentication และ FirebaseUI (คืออะไรน้าาา เดี๋ยวอ่านไปจะมีบอกจ้า)
  • มีการพิมพ์ comment ใน guestbook แล้วเก็บข้อมูลเข้าไปใน Cloud Firestore
  • แน่นอนว่าการเขียน/อ่านข้อมูล เรื่อง Security Rules ก็สำคัญนะ
  • deploy web app ขึ้นไปบน Firebase Hosting

2) เริ่มการทำการเขียนโค้ดกันเถอะ

จากนั้นเราก็ clone project ออกมา โดยการกดเข้าไปที่ลิ้งนี้จ้า (ข้างล่างก็อลังการงานสร้างจนงง เหมือนทำผ่านตรงนี้ได้เลยแหะ)

https://stackblitz.com/edit/firebase-gtk-web-start

พอเข้าไปแล้วกด fork จ้าเพื่อ clone มาเป็นของเรา เปิดมาเจอ @anonymous ไม่ต้องตกใจเน้อ เพราะเรายังไม่ได้ login ผ่าน Github นั่นเอง หน้าตาจะประมาณนี้เนอะ

ส่วนประกอบคร่าวๆของเจ้า Stackblitz

  • ด้านซ้าย เป็นที่อยู่ชองไฟล์ในโปรเจกเรา ซึ่งจริงๆสามารถสลับไปเป็น Firebase หรืออื่นๆ จะว่าไปหน้าตาคล้าย Visual Studio Code เหมือนกันแหะ
  • ตรงกลาง หน้าจอ Editor เอาไว้เขียนโค้ด เอ้อออคล้าย Visual Studio Code อีกหล่ะ
  • ด้านขวา ส่วน live preview แบบโค้ดปุ๊ป รันปั๊ป แสดงบัคอย่าง realtime เอ้ยยย แสดงผลแบบ realtime ถ้าพิมพ์ error มันก็ error แบบ realtime เช่นกัน

3) ลองแก้ข้อมูล event กันก่อน ซึ่ง tag ที่แก้ได้ก็มีหลายที่ ไม่ว่าจะเป็นชื่อ event วันที่ สถานที่ รายละเอียด event

ในที่นี้เราจะแก้ section ที่ชื่อว่า event-details-container โดยเปลี่ยน location_city เป็น Bangkok, Thailand จ้า ซึ่งทางนี้ย้อนแก้ wording ทีหลังตอนก่อนส่งการบ้านจ้า

ส่วนนี้เขาต้องการให้เราชินกับ detail ต่างๆใน HTML ก่อนจ้า ว่าอะไรอยู่ไหน แล้วก็เป็นการหัดใช้ Stackblitz ไปในตัวด้วยจ้า

4) สร้างโปรเจก Firebase และเตรียมเชื่อต่อสิ่งต่างๆ

ก่อนอื่นเราสร้าง project Firebase จุดสำคัญ คือ Enable Google Analytics for this project ซะ เพราะเราไม่ได้ใช้ Google Analytics นั่นเอง

จากนั้นไปที่ Firebase Authentication เพื่อ enable email sign-in นั่นเอง

และไปกันต่อที่ Cloud Firestore เพื่อสร้าง database โดย security rules ในตอนนี้เลือกแบบ test mode ไปก่อน เดี๋ยวเราจะแก้ทีหลังน้าาา

อันนี้เน้นยํ้าหนักๆ Cloud Firestore location นั้น หลังจากสร้างแล้วจะเปลี่ยนไม่ได้อีกแล้วนะ ซึ่งทางพี่ตี๋เองก็บอกไปทาง Firebase แล้วเช่นกัน และไม่ใช่ประเทศเราประเทศเราที่อยากจะเปลี่ยน location เลย หลายๆประเทศก็เช่นกัน (ตอนนั้นก็หาวิธีอยู่ตอนที่ลองทำหลังบ้าน พบว่าเปลี่ยน location ของ Cloud Function ได้ แต่ Cloud Firebase ไม่ได้ แล้วเป็น project ที่นานมากแล้วด้วยง่ะ)

เรามีโอกาสเลือกเพียงครั้งเดียว ดังนั้น เราจะเลือก location ที่ใกล้บ้านเรามากที่สุด คือ asia-east2 อยู่ที่ฮ่องกงนั่งเอง (ถ้ามีของสิงคโปรก็เลือกกันไปนานแล้ว แต่นี่ไม่มีงายย) โดยการเลือก location นั้น เราจะพิจารณาจากคนใช้เป็นหลัก เพื่อให้แอพที่เราทำนั้นมีประสิทธิภาพและ performance ดีๆเนอะ

5) มา config ในแอพเรากันเถอะ

กลับไปที่ Stachblitz ไปที่ index.js เพื่อ import ของต่างๆเข้ามา และเราไม่ต้องทำเองด้วยจ้า ในนั้นเขาใส่มาให้พร้อมล้าววว สิ่งที่ต้อง import library ก็จะมี Firebase Authentication, Cloud Firestore และ FirebaseUI ใช้ตอน Authentication ก็คือส่วน login เราไม่ต้องเขียน view ขึ้นมาเอง ใช้

และเพิ่มเว็บเราใน Firebase Project ที่เพิ่งสร้างมะกี้

ใส่ชื่อเล่นของโปรเจกของเราไป และยํ้าหนาๆว่า ยังไม่ต้องติ๊กตรง Also set up Firebase Hosting for this app นะ เพราะเราใช้เจ้า Stachblitz ในการ preview เว็บเรานะ เสร็จแล้วกด Register app

หลังจากนั้น เราจะได้ key มาชุดนึง ไปแปะไว้ใน index.js ซึ่งทางเขาจะมี comment ไว้ให้เราแปะได้ถูกที่และไม่ล่กจ้า แปะไปดังนี้

และอย่าลืม init Firebase ด้วยนะจ๊ะ

แล้วถ้าลืมก้อปทำไงง่ะ ไปที่ setting > project setting ไปหาแอพของเรา ไปตรง your app จะมี key ต่างๆไว้ตรงน้านจ้า เลือก config เน้อ

6) ทำส่วน Authentication เพื่อ sign in ก่อนกด RSVP โดยการแสดงเจ้า Firebase UI ซึ่งตอนนี้ยังเป็น prebuild library อยู่นะจ๊ะ เพื่อให้ user login โดยที่เราไม่ต้อง coding UI เพิ่มเลย ดีจัง

ก่อนอื่น init มันก่อน ไปที่ index.js แล้วใส่ส่วนนี้ไว้ล่างสุดเลยจ้า

// Initialize the FirebaseUI widget using Firebase
const ui = new firebaseui.auth.AuthUI(firebase.auth());

ไปที่ index.html แล้วใส่ปุ่มกันต่อเลยจ้า

<section id="event-details-container">
    <!-- ... -->
    <!-- ADD THE RSVP BUTTON HERE -->
    <button id="startRsvp">RSVP</button>
</section>

และใส่ action ของปุ่มลงไปที่ index.js

// Listen to RSVP button clicks
startRsvpButton.addEventListener("click",
 () => {
      ui.start("#firebaseui-auth-container", uiConfig);
});

ลองกดดูหน่อยสิตัวเธอ การทำงานพอกดตุ่ม RSVP แล้ว เราสามารถ login เข้าไปในหน้าเว็บได้จ้าา หน้าตาจะประมาณนี้

ความฉลาดของเจ้า Firebase UI ก็คือ ถ้า account ไหนยังไม่ได้ register จะมี form ให้กรอก แบบนี้ๆ

เมื่อเรา register เสร็จแล้ว ไปดูที่ Firebase Authentication ว่า account ของเราสร้างไปหรือยัง และแล้วน้อง account ใหม่ที่เพิ่งสร้างก็มาแล้วว

สมัครเสร็จแล้วยังไงต่อนะ เราต้อง handle เพิ่มนี่นาา เพราะเมื่อกี้กดไปก็ไม่ได้มีอะไรเกิดขึ้นเลยในหน้าเว็บของเรา ใส่ current authentication state เพื่อ check ว่าเรา login อยู่ไหมนะ ไปที่ index.js ไปลงไปที่ท้ายไฟล์เช่นเคย โดยเรียก onAuthStateChanged ดังนี้

// Listen to the current Auth state
firebase.auth().onAuthStateChanged((user)=> {
  if (user) {
    startRsvpButton.textContent = "LOGOUT"
  }
  else {
    startRsvpButton.textContent = "RSVP"
  }
});

โดยรวม คือการเปลี่ยน text ของปุ่มตาม state นั่นเอง โดยถ้าเรา login แล้ว ปุ่มจะขึ้นคำว่า LOGOUT และตอนยังไม่ login จะขึ้นว่า RSVP

แต่ยังไม่ถูกเนอะ เพราะถ้าเรากด logout มันก็เป็นการเปลี่ยน state เนอะ เพราะเรา sign out ออกจากระบบ ใส่ condition เพิ่มเสียหน่อยจ้า

// Called when the user clicks the RSVP button
startRsvpButton.addEventListener("click",
 () => {
    if (firebase.auth().currentUser) {
      // User is signed in; allows user to sign out
      firebase.auth().signOut();
    } else {
      // No user is signed in; allows user to sign in
      ui.start("#firebaseui-auth-container", uiConfig);
    }
});

ลอง logout และ login ใหม่ จะได้แบบนี้

7) ทำส่วน guestbook กันต่อจ้า

data model ของระบบจะเป็นดังนี้

ทบทวนกันหน่อยเน้อ Cloud Firestore นั้นเป็น database แบบ NoSQL มีโครงสร้างแบบ document เนอะ ให้นึกถึงแฟ้มใส่เอกสารนะ

  • collection คือ guestbook เสมือนเป็นแฟ้ม
  • ส่วน document คือ message เสมือนเป็นเอกสารในแฟ้ม
  • แต่ละ field ของ document เสมือนข้อความในเอกสารนั้นๆ มี name, text, timestamp, และ userId โดย name และ UserId นั้นได้มาจากตอน create account นั่นเอง
ถ้าอยากอ่านเกี่ยวกับ Cloud Firestore เพิ่ม ลองอ่าน use case ของเราได้จ้า
ทำ API กับ Cloud Firestore ด้วย Cloud Functions for Firebase
ด้วยความที่เราอยากย้ายบล็อกใหม่ๆมาลง Firebase Hosting ของเรา เลยเอา data จาก blogspot มาลง Cloud Firestore แล้วก็ต้องสร้าง API…

จากนั้นทำการเตรียม write data ลงคุณ Cloud Firestore กันต่อ ไปที่ index.html แล้วหา section ที่ชื่อว่า guestbook-container เพื่อเพิ่ม view ในส่วน guestbook ดังนี้

<section id="guestbook-container">
   <h2>Discussion</h2>

   <form id="leave-message">
     <label>Leave a message: </label>
     <input type="text" id="message">
     <button type="submit">
       <i class="material-icons">send</i>
       <span>SEND</span>
     </button>
   </form>

 </section>

พอได้หน้าตามาแล้ว ไป handle ปุ่มส่งข้อความกันต่อเลยจ้า ด้วย addEventListener ที่ index.js

// Listen to the form submission
form.addEventListener("submit", (e) => {
 // Prevent the default form redirect
 e.preventDefault();
 // Write a new message to the database collection "guestbook"
 firebase.firestore().collection("guestbook").add({
   text: input.value,
   timestamp: Date.now(),
   name: firebase.auth().currentUser.displayName,
   userId: firebase.auth().currentUser.uid
 })
 // clear message input field
 input.value = ""; 
 // Return false to avoid redirect
 return false;
});

เมื่อกดปุ่มแล้ว ข้อความที่เราพิมพ์ไป จะถูกเขียนใน collection ที่ชื่อว่า guestbook โดยเพิ่ม field ต่างๆ คือ text เป็นข้อความที่เราพิมพ์ไป timestamp ส่งเวลาตอนนี้ไป ส่วน name และ timestamp ส่งจาก user ของเราที่ login ผ่าน Firebase Authentication ไป เมื่อเพิ่มข้อมูลไปยัง Cloud Firestore เสร็จแล้ว ทำการเคลียร input ซะ

แน่นอนว่าส่วน guestbook จะให้คนมาพิมพ์ใส่ได้ เมื่อ user คนนั้น login เข้ามาในระบบแล้วเท่านั้น (ไม่งั้นจะพังเนอะ เพราะส่ง name กับ userId ไปด้วย) ดังนั้นเราจะต้องทำการซ่อน view นี้เมื่อ user ไม่ได้ login ใน onAuthStateChanged แบบนี้

// Listen to the current Auth state
firebase.auth().onAuthStateChanged((user) => {
 if (user){
   startRsvpButton.textContent = "LOGOUT";
   // Show guestbook to logged-in users
   guestbookContainer.style.display = "block";
 }
 else{
   startRsvpButton.textContent = "RSVP";
   // Hide guestbook for non-logged-in users
   guestbookContainer.style.display = "none";
 }
});

ลองกดส่งข้อความดูสิ

ส่งเสร็จไปไหน ต้องไป Cloud Firestore สิเธอ พบว่าทำงานได้ถูกต้อง ตบมือไป 3 ล้านครั้ง

และเมื่อเรา logout มันต้องไม่มีช่องให้พิมพ์ comment เนอะ แบบนี้

ปล. สำหรับคนที่อาจจะพิมพ์ตามไม่ทันในสตรีมสด หรือลองทำเองแล้วตามไม่ทัน สามารถกดไปดูที่ checkpoint นะจ๊ะ

8) ที่พิมพ์ๆไป เอามาแสดงในหน้าเว็บสิ

เพิ่ม view กันสักนิด ไปที่ index.html ใน section guestbook-container เพิ่ม section ที่ชื่อว่า guestbook ลงไป

<section id="guestbook-container">
   <h2>Discussion</h2>

   <form><!-- ... --></form>

   <section id="guestbook"></section>

 </section>

จากนั้นมา implement การแสดงผลใน section ที่ชื่อว่า guestbook กันต่อ ที่ index.js เพื่อดึง data ที่มีใน Cloud Firestore ขึ้นมาแสดง

// Create query for messages
firebase.firestore().collection("guestbook")
.orderBy("timestamp","desc")
.onSnapshot((snaps) => {
 // Reset page
 guestbook.innerHTML = "";
 // Loop through documents in database
 snaps.forEach((doc) => {
   // Create an HTML entry for each document and add it to the chat
   const entry = document.createElement("p");
   entry.textContent = doc.data().name + ": " + doc.data().text;
   guestbook.appendChild(entry);
 });
});

ดึง data จาก collection guestbook โดย order ตามวันล่าสุดลงมา โดยตอนที่ดึงจะ reset data ก่อน แล้ววน loop แสดงชื่อและ comment ขึ้นมาจนครบ แบบนี้

9) ก่อนออกสู่ production อย่าลืมแก้ security rule ก่อนนะจ๊ะ

จำได้ไหม ตอนที่เราสร้าง Cloud Firestore มันจะถามว่าเอา security rule แบบไหน และเราเลือก test mode ไป จำได้เป่าาาาา? ไม่แนะนำให้ใช้ test mode ที่ allow read และ write บน production นะ เพราะคนอื่นเขาสามารถแกะดูได้ว่าเรา config อะไรไว้

เราจะให้ user ที่ login แล้วเท่านั้น สามารถเข้าไปเขียน guestbook ได้ ดังนั้นเราใส่ match /databases/{database}/documents ลงไป โดยคนที่อ่านได้ คือทุกคนที่ login แล้ว และคนที่เข้าไปเขียนได้ คือ user คนนั้นๆนั่นเอง สรุป คนอื่นที่ login อ่านได้หมด แต่เจ้าของข้อความเป็นคนเขียนเอง

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /guestbook/{entry} {
      allow read: if request.auth.uid != null;
      allow write:
        if request.auth.uid == request.resource.data.userId;
    }
  }
}

และเพิ่มความมั่นใจกันสักนิด นอกจากจะ check userId แล้ว ยัง check name, text แบะ timestamp ด้วยเพื่อ make sure จ้า

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /guestbook/{entry} {
      allow read: if request.auth.uid != null;
      allow write:
      if request.auth.uid == request.resource.data.userId
          && "name" in request.resource.data
          && "text" in request.resource.data
          && "timestamp" in request.resource.data;
    }
  }
}

จากนั้นทำการ reset listener มี best practice บอกไว้ว่าาาา เมื่อเรา add listener ไปแล้ว เราควร unsubscription เพื่อไม่ให้ทำงานไปเรื่อยๆให้เปลือง bandwidth จ้า

ดังนั้นไปสร้าง function ที่ index.js โดยตอนนี้สร้าง 2 function คือ subscribeGuestbook() เพื่อ update message ใน guestbook

// Listen to guestbook updates
function subscribeGuestbook(){
   // Create query for messages
 guestbookListener = firebase.firestore().collection("guestbook")
 .orderBy("timestamp","desc")
 .onSnapshot((snaps) => {
   // Reset page
   guestbook.innerHTML = "";
   // Loop through documents in database
   snaps.forEach((doc) => {
     // Create an HTML entry for each document and add it to the chat
     const entry = document.createElement("p");
     entry.textContent = doc.data().name + ": " + doc.data().text;
     guestbook.appendChild(entry);
   });
 });
};

และ unsubscribeGuestbook()

// Unsubscribe from guestbook updates
function unsubscribeGuestbook(){
 if (guestbookListener != null)
 {
   guestbookListener();
   guestbookListener = null;
 }
};

จากนั้นไปใส่ function ที่เพิ่งสร้างไว้ ไปใส่ใน onAuthStateChanged

firebase.auth().onAuthStateChanged((user) => {
if (user){
  startRsvpButton.textContent = "LOGOUT";
  // Show guestbook to logged-in users
  guestbookContainer.style.display = "block";

  // Subscribe to the guestbook collection
  subscribeGuestbook();
}
else{
  startRsvpButton.textContent = "RSVP";
  // Hide guestbook for non-logged-in users
  guestbookContainer.style.display = "none";

  // Unsubscribe from the guestbook collection
  unsubscribeGuestbook();
}
});

10) deploy บน Firebase Hosting เสียที ซึ่งใน Stackblitz เขาก็จัดการให้เราแล้วหล่ะ

ก่อนอื่น login github ก่อน ซึ่งเมลล์ที่ใช้ใน github นั้น จะต้องตรงกับเมลล์ที่ใช้ใน Firebase ที่เราสร้าง project กันไปเมื่อกี้น้าาาา

กดไปที่แท็ป Firebase เพื่อ Sign in เข้า Firebase จากนั้นเลือก project ของเราที่เพิ่งสร้างไปมะกี้

เมื่อเลือกโปรเจกเรียบร้อยจะมีปุ่มเชื้อเชิญมาบอกเราว่า deploy ฉันสิ~

จากนั้นก็นับหนึ่งถึงสามไม่ล้าน รอให้มัน deploy เสร็จ

จากนั้นกด Open live site ก็จะเจอเว็บที่เราทำๆกันใน Firebase Hosting แล้วจ้า

11) มี bonus ให้เพิ่มเสียหน่อย

เมื่อเราอยากรู้ว่า มีคนจะมา event ของเรากี่คน เราก็ทำปุ่มเพื่อให้สามารถ check จำนวนคนได้ว่า จะมากันกี่คน จะได้เตรียมพิซซ่าและนํ้าอัดลมกันได้ถูก (แบบอินเนอร์คนเคยจัดงาน meetup มาหนึ่งครั้งถ้วน)

เพิ่มปุ่มกันก่อน ไปที่ index.html หา section guestbook-container ใส่สิ่งนี้ไว้ด้านบนของ Discussion

<h2>Are you attending?</h2>
<button id="rsvp-yes">YES</button>
<button id="rsvp-no">NO</button>

น้องปุ่มมาแล้ว มา handle ตอนกดปุ่มเพิ่มกันสักหน่อย แน่นอนไปที่ index.js เนอะ ให้แสดงจำนวนคนโดยมีค่า attending เป็น true

// Listen for attendee list
firebase.firestore()
.collection('attendees')
.where("attending", "==", true)
.onSnapshot(snap => {
 const newAttendeeCount = snap.docs.length;

 numberAttending.innerHTML = newAttendeeCount+' people going'; 
})

อาจจะมีอาการงงๆ คืองี้ เราสร้าง collection ใหม่ขึ้นมาอีกตัวนึงชื่อว่า attendees เอาไว้เก็บคนที่ตอบรับ และคนนั้นมาหรือไม่มางานนี้เนอะ ตัว document นั้นจะเป็น userId ของเรานั่นเอง ซึ่งถ้ากด YES ก็จะเขียนค่า attending เป็น true

// Listen to RSVP responses
rsvpYes.onclick = () => {
 // Get a reference to the user's document in the attendees collection
 const userDoc = firebase.firestore().collection('attendees').doc(firebase.auth().currentUser.uid);

 // If they RSVP'd yes, save a document with attending: true
 userDoc.set({
   attending: true
 }).catch(console.error)
}

ถ้ากด NO ก็จะเขียนค่า attending เป็น false

rsvpNo.onclick = () => {
 // Get a reference to the user's document in the attendees collection
 const userDoc = firebase.firestore().collection('attendees').doc(firebase.auth().currentUser.uid);

 // If they RSVP'd yes, save a document with attending: true
 userDoc.set({
   attending: false
 }).catch(console.error)
}

ทำไมมันเร็วจังง่ะตอนกดปุ่ม สำหรับคนที่เขาเล่น Cloud Firestore จนพรุนหมดแล้ว เขาจะรู้ว่า เพราะว่ามัน write ใน local ก่อนนั่นเองงงงง~

หน้าตาก็จะประมาณนี้จ้า

และหน้าตาเว็บที่ได้แบบสมบูรณ์พูนผล

https://fir-web-codelab-7ce05.firebaseapp.com/?43361

12) เรียนจบแล้วไปไหน ในนี้มีการทบทวนและสรุป และเราก็จะได้ badge มาประดับ profile ของเรา สิ่งที่เขาให้มาเพิ่ม คือ codelab Firebase อื่นๆ

google.dev
In this codelab, you&#39;ll learn how to use the Firebase platform on the web by building a chat app.

และคลิป Cloud Firestore ให้เราไปฟังเพิ่มกันจ้า

ทำเสร็จแล้วยังไงต่อนะ?

พอไปถึง Congratulation ก็จะมี popup เด้งมาว่าให้ Sign in เพื่อรับ badge ซะ แน่นอนว่าขึ้นไวจนทางนี้ แคปรูปไม่ทันจ้า แงงงงงง

เมื่อทำ codelab เสร็จจะมี popup แบบนี้ออกมาข้างล่างจอ แน่นอนว่าแคปจากบทเรียนอื่นมาจ้า

เมื่อกดดันจนได้ที่ เอ้ยยย กดปุ่ม Done จะพาไปหน้านี้จ้า

แล้ว badge เราจะเห็นได้ไง ก่อนอื่นกดที่ My Profile ก่อน จะมีให้กรอกชื่อ-สกุล ที่ทำงาน ให้เรียบร้อย แล้วก็เพิ่มรูป จากนั้นเราก็ allow ให้ webcam ถ่ายรูปเรา จากนั้นระบบจะทำการแปลงหน้าเราเป็น avatar ด้วย AI จ้า

เมื่อเรียบร้อยแล้วเราจะได้ avatar ใหม่จากทาง Google เพื่อเอาไปเปลี่ยนรูป profile ใน Facebook เอ้ยยย ได้หน้า My Profile ของเราพร้อม badge ที่เราทำ codelab เมื่อกี้มาเรียบร้อย

http://google.dev/u/me

และมีกิจกรรมร่วมสนุกคือ ส่งการบ้านโดยการแปะลิ้ง url ของเว็บที่เราทำแล้ว deploy ไปยัง Firebase Hosting และแคปหน้าจอ profile ตัวเองที่มี badge ไปยังลิ้งใต้รูปล่าง ซึ่งผู้ส่งการบ้านครบ 20 คนแรกนั้น จะได้บัตรงาน Firebase Dev Day 2020 ที่จะจัดในปลายปีนี้จ้า อู้ววววววว ด้วยความที่เราแคปหลายอย่างเตรียมไว้จดบล็อก เลยส่งการบ้านได้เร็วไวเลยจ้า

https://www.facebook.com/events/505235653687580/permalink/507040576840421/

และส่ง feedback ให้กับทาง Google ได้ดังนี้จ้า เพื่อให้เรามีกิจกรรมดีๆแบบนี้ในครั้งต่อไปจ้า

Firebase Study Jams - Attendee Feedback Form
Firebase is Google’s mobile app development platform for iOS, Android, and mobile web developers. Firebase gives you functionality like analytics, databases, messaging and crash reporting so you can move quickly and focus on your users. Firebase Study Jams for Web are a great opportunity to bring m…

บ่ายวันนี้ก็สนุกสนานมาก มีไลฟ์หมุนค้างนิดหน่อย แต่ทีมงานก็แก้ไขได้รวดเร็ว และมีการย้อนไปในตรงที่หลุดด้วยจ้า ช่วงหลังๆมีการบอกว่าพี่ตี๋ไปจิบนํ้าส้มตอนไลฟ์ค้างด้วย แล้วในช่องแชทมีการเล่นมุขโน้นนี่กันด้วย จุดที่ขยี้สุดๆ ก็ตรง เมลล์พี่ตี๋ที่ในไลฟ์ใส่ @hotmail.com แล้วพี่เอกบอกว่าเมลล์แรกของพี่ตี๋น่าจะ @chaiyo.com มากกว่า เอ่อออ เราไม่คุ้นๆเลยอ่าง่า เหมือนเกิดไม่ทันอะค่าาาา (หราาาา) และทางเราตื่นเต้นว่าวันนี้จะได้อะไรกลับไป รู้แต่เขียนเว็บอ่ะวันนี้ ฮ่าๆ

ก่อนจากกัน แอบสงสัยว่าในนั้นมีอะไรให้เล่นอีกไหมนะ เข้าใจว่าน่าจะเป็นเว็บ codelab แบบใหม่ ฉบับ beta นะเออ แล้วฝั่ง Android มีอะไรให้เล่นบ้างนะ

https://google.dev/topics/android?hl=en

ไส้ในแต่ละ pathways จะมี codelab ย่อยๆ แตกต่างกันไปในแต่ละเนื้อหา

https://google.dev/pathways/beta/mdc-kotlin?hl=en

กดไปดูพบว่าข้างในจะเป็น codelab เดิม อย่างอันนี้เป็น Material Design ด้วย Kotlin

ท้ายสุด รู้อะไรไม่สู้ลงมือทำจ้า เพราะหลายอย่างเราก็ไม่เคยทำจริงๆนะ ฮ่าาาๆๆ

ปล. สรุปบล็อกดันนานกว่าทำใน study jam อีกง่าาาาา


สุดท้ายฝากร้านกันสักนิด ฝากเพจด้วยนะจ๊ะ

อย่าลืมกด like กด share บทความกันด้วยนะคะ :)

Posted by MikkiPastel on Sunday, December 10, 2017

Tags

Minseo Chayabanjonglerd

I am a full-time Android Developer and part-time contributor with developer community and web3 world, who believe people have hard skills and soft skills to up-skill to da moon.