สร้าง Cron Job ด้วย Cloud Functions for Firebase ง่ายนิดเดียว

Jirawatee
Firebase Thailand

--

หนึ่งในความสามารถของ Cloud Functions for Firebase คือการสร้าง API ให้นักพัฒนาสามารถเรียกใช้จากภายนอกได้ โดยคำถามหนึ่งที่ทีม Firebase ได้รับบ่อยๆคือ จะ schedule ฟังก์ชันเหล่านั้นแบบ Cron Job ได้อย่างไรบ้าง

ก่อนหน้านี้ทีม Firebase ก็แนะนำว่าให้ไปใช้ App Engine, Cloud Pub/Sub หรือ thrid-party อย่าง cron-job.org ในการ schedule เพื่อเรียก API เหล่านั้น

แต่การไปสร้าง scheduler ใน App Engine หรือ Cloud Pub/Sub ก็จะมี learning curve สำหรับคนที่ยังไม่เคยไปสัมผัสมาก่อน หรือแม้กระทั่งการใช้งาน thrid-party ก็ถือว่าไม่ปลอดภัยซะทีเดียวเนื่องจาก Endpoint URL ของเรา ได้ถูก publish ออกไป ซึ่งแปลว่าใครรู้ URL ก็สามารถ request ได้นั้นเอง

และเมื่อไม่นานมานี้เองทีม GCP ได้ออกบริการใหม่ชื่อ Cloud Scheduler ซึ่งเป็นบริการให้เรา schedule ตัว API และ Cloud Pub/Sub ได้ ทีม Firebase จึงไม่รอช้าที่จะพัฒนาโซลูชั่นแบบครบวงจรใน Cloud Functions for Firebase บน Cloud Scheduler เพื่อความปลอดภัยในการ schedule ฟังก์ชัน ให้ง่ายกว่าทุกทางที่เคยแนะนำไป และทำงานได้ 24 x 7 แถม recurring ได้ด้วย

ลงมือ

ก่อนจะไปดูวิธีการ ใครที่ยังไม่รู้จัก Cloud Functions for Firebase จงไปทำความรู้จัก และติดตั้งให้พร้อมกับการพัฒนากันก่อนที่บทความนี้

สิ่งแรกที่ทุกคนต้องทำ ก็คือตรวจสอบดูก่อนว่าเครื่องมือเราอัพเดทล่าสุดหรือยัง โดย Firebase CLI ต้องเป็นเวอร์ชันตั้งแต่ 6.7.1 ขึ้นไป และ firebase-functions ต้องเป็นเวอร์ชันตั้งแต่ 2.3.0 ขึ้นไป จึงจะใช้งานได้ หากเก่ากว่านี้ให้อัพเดทตามนี้ที่โฟลเดอร์ functions ของตะเองนะ

npm install firebase-functions@latest --save
npm install -g firebase-tools

เมื่อพร้อมแล้ว มาดูตัวอย่างกัน โดยผมจะตั้งเวลาให้ฟังก์ชันพ่น log ทุกนาที

exports.scheduledFunction = functions
.pubsub.schedule("* * * * *")
.timeZone('Asia/Bangkok')
.onRun((context) => {
console.info("This will be run every minute!");
});

ดูผลลัพธ์ที่ได้ใน Firebase Console เพื่อยืนยันความสำเร็จกันหน่อย

เฮ้ย! แล้วโค้ดมันสั้นแค่นี้เหรอ? …เออ แค่นี้แหละ จริงๆ :)
แต่ผู้อ่านคงงงว่า ดอกไม้จันทร์ 5 ดอก(“* * * * *”) มันคืออะไรช่ายมะ งั้นมาดูรูปกัน

แต่ละหลัก แทนที่เรื่องของวันเวลาที่เราจะ schedule

  • min: 0 - 59
  • hour: 0 - 23
  • day of the month: 1 - 31
  • month: 1 - 12
  • day of the week: 0 - 7

ตัวอย่างเช่น

"* * * * *" = ทุกนาทีเพื่อเธอ"*/5 * * * *" = ทุก 5 นาที"30 10 * * *" = ทุกวัน เวลา 10:30"0 */1 * * *" = ทุกชั่วโมง"0 9 * * 1" = ทุกวันจันทร์เวลา 09:000 17 * * 1-5 = ทุกจันทร์ - ศุกร์ เวลา 17:00

นอกจากนี้เรายังสามารถเปลี่ยน “* * * * *” ไปเป็นประโยคที่บอกเวลา(ภาษาอังกฤษ) ได้

"every 1 mins" = ทุกนาที"every 1 hours" = ทุก 1 ช.ม"every day 00:00" = ทุกวันตอนเที่ยงคืน"every mon 09:00" = ทุกวันจันทร์ เวลา 09:00"every 5 mins from 10:00 to 14:00" = ทุก 5นาที ตั้งแต่ 10:00-14:00"1,3,5 of month 09:00" = ทุกวันที่ 1, 3, 5 ของเดือน เวลา 09:00"1st,3rd fri of month 12:00" = ศุกร์แรกและศุกร์ที่สามของเดือนเวลาเที่ยง"1st wed of mar,apr 12:00" = พุธแรกของเดือน มี.ค และ เม.ย เวลาเที่ยง"1 of jan,july 00:00" = ทุกวันที่ 1 ของเดือน ม.ค และ ก.ค เวลาเที่ยงคืน

ตัวอย่างเต็มๆ กับการเอาไปใช้งานจริงกับ LINE Chatbot

Hooray! มีการรายงานสภาพอากาศมาให้ทุกนาทีเรียบร้อย

สิ่งที่คุณต้องรู้

  1. แพลนใน Firebase ต้องเป็น Blaze เท่านั้นจึงจะใช้งาน scheduler ได้
  2. ถ้าไม่ระบุ timeZone จะมีค่าเริ่มต้นเป็น America/Los_Angeles
  3. เวลาที่น้อยที่สุดที่สามารถตั้งได้ คือทุก 1 นาที
  4. ฟรี 3 Jobs / บัญชี Google / เดือน (ไม่จำกัดจำนวน request)
  5. กรณีมี Job มากกว่า 3 จะมีค่าใช้จ่าย 1 Job / $0.1(~3 บาท) / เดือน
  6. สามารถปิด Job นั้นๆได้ด้วยการลบโค้ดแล้ว deploy (ห้ามไปลบเองใน console เพราะงานอาจจะเข้า)

ก่อนจากกันไป

หวังว่าบทความนี้จะเป็นประโยชน์กับผู้ที่ต้องการตั้ง Cron Job ให้ปลอดภัยและง่ายในการพัฒนา อีกทั้งยืดหยุ่นมากๆสำหรับการตั้งเวลา ซึ่ง use case หนึ่งที่ผมนึกออกก็คือ Cron Job วันหวยออก ทุกวันที่ 1 และ 16 ของทุกเดือนช่วงเวลา 16:30 เราก็สามารถทำได้อย่างง่ายดายละ สำหรับวันนี้ขอตัวลาไปก่อน จนกว่าจะพบกันใหม่บทความหน้า ราตรีสวัสดิ์พี่น้องนักพัฒนาชาวไทย

--

--

Jirawatee
Firebase Thailand

Technology Evangelist at LINE Thailand / Google Developer Expert in Firebase