รู้จัก Cloud Functions for Firebase 2nd Gen ตั้งแต่ Zero จนเป็น Hero

Jirawatee
Firebase Thailand
Published in
8 min readJan 14, 2024

--

ในการพัฒนาแอปพลิเคชันส่วนใหญ่ ณ วันนี้ก็ต้องมี server ที่คอยทำงานอยู่เบื้องหลัง ด้วยข้อดีหลายๆอย่าง เช่น เพื่อ centralize ข้อมูลและ logic การทำงานไว้ที่จุดๆเดียว, เพื่อรองรับการใช้งานจากหลายๆแพลทฟอร์ม, เพื่อความปลอดภัยที่มากขึ้น หรือจะเพื่อให้ client ไม่ต้องทำงานหนัก

แต่การจะตั้ง server เองก็ไม่ใช่เรื่องง่าย เพราะมันมีเรื่องที่ต้องให้คำนึงอยู่หลายเรื่องเหมือนกัน ไม่ว่าจะเป็นการ scale ที่ควรจะต้องขึ้นลงได้ตาม transaction ที่เกิดขึ้น, เรื่องของความปลอดภัย, เรื่องการเตรียม API หรือ SDK ที่จะรองรับการใช้งานแบบ seamless จากหลายๆแพลทฟอร์ม, หรือค่าใช้จ่ายทั้ง ฮาร์ดแวร์, ซอฟต์แวร์ และผู้เชี่ยวชาญที่จะเข้ามาดูแลตรงส่วนนี้

มือใหม่ที่กำลังคิดจะสร้างแอปพลิเคชัน ฟังดูก็คงหัวจะปวดอยู่เหมือนกัน แต่ไม่ต้องกังวลไป เพราะบทความนี้จะพาคุณไปรู้จัก Cloud Functions for Firebase อีกหนึ่งทางเลือก ที่เตรียมทุกสิ่งทุกอย่างที่กล่าวไปข้างต้นไว้ให้แล้ว พร้อมให้คุณเขียนโปรแกรมตาม business logic ที่คุณต้องการได้เลย

Cloud Functions for Firebase เป็นบริการแบบ Functions-as-a-Service ที่จะให้นักพัฒนาเขียนและ run โค้ดบน Google infrastructure เพื่อตอบสนอง event ต่างๆที่เกิดขึ้นจากบริการใน Firebase และ HTTP Requests

Event Triggers

เป็นการสร้างฟังก์ชันเพื่อเฝ้าดูความเปลี่ยนแปลง(subscribe)ที่เกิดขึ้นกับบริการต่างๆ Firebase ซึ่งเมื่อมีความเปลี่ยนแปลงเกิดขึ้น ตัวบริการที่เราเฝ้าดูจะส่งสัญญาณพร้อมกับข้อมูลมา(publish)ให้ฟังก์ชันทำงานต่อแบบอัตโนมัติ ซึ่ง ณ วันนี้ก็มีบริการมากมายที่สามารถทำงานร่วมกับ Cloud Functions ได้

เพื่อให้เห็นภาพ เรามาดูตัวอย่างการ trigger จากบริการใน Firebase ด้านล่างนี้กัน

จากภาพเราสามารถสร้างฟังก์ชันขึ้นมา(2) เพื่อเฝ้าดูการเปลี่ยนแปลงของฐานข้อมูลอย่าง Firestore หรือ Realtime Database ได้ เช่น เมื่อข้อมูลผู้ใช้ใหม่ถูก write เข้ามาเก็บลงฐานข้อมูล ตัวฐานข้อมูลจะส่งสัญญาณพร้อมกับข้อมูลผู้ใช้ มาให้ที่ฟังก์ชันของเรา เราก็สามารถเขียนโปรแกรมในฟังก์ชันของเราให้ส่งข้อความไปทักทายเครื่อง client ได้เป็นต้น

HTTP Requests

เป็นการสร้างฟังก์ชันที่เป็น API หรือ Webhook เพื่อรอรับการ request ผ่าน HTTP ให้ฟังก์ชันที่เขียนไว้ทำงานต่อ และเพื่อให้เห็นภาพ เรามาดูตัวอย่างการ trigger จาก HTTP Requests ด้านล่างนี้กัน

จากภาพเราสามารถสร้าง Webhook API(Functions) ขึ้นมาเพื่อรอรับ webhook events จาก GitHub เช่น เมื่อมีสมาชิกในทีม push โค้ดขึ้นมาใน repo ตัว GitHub ก็จะส่ง request พร้อมข้อมูลมาที่ Webhook API ของเรา ซึ่งเราก็สามารถเขียนโปรแกรมเพื่อส่งต่อข้อมูลเหล่านั้นไปให้เพื่อนร่วมทีมคนอื่นๆในห้อง Slack ได้เป็นต้น

Tip: เรายังสามารถสร้างฟังก์ชันที่ให้แอปเรียกหาตรง หรือที่เรียกว่า Callable Functions โดยไม่ต้องระบุ Endpoint URL ลงไปในโค้ดได้ด้วยนะ ใครสนใจก็อ่านบทความด้านล่างนี้ได้เลย

Schedule Functions

นอกเหนือจาก trigger ทั้ง 2 แบบที่กล่าวไปข้างต้น Cloud Functions for Firebase ยังได้ร่วมมือกับทีม Cloud Scheduler ออก Schedule functions ที่ให้เราสร้าง Cron Job แบบง่ายๆด้วยโค้ด 2–3 บรรทัด ใครสนใจอ่านเรื่องนี้จากบทความได้เลย

1. รู้จักกับ Cloud Functions for Firebase 2nd Gen

ในงาน Google I/O ปีที่ผ่านมาทีม Firebase ก็ได้เปิดตัว Cloud Functions 2nd Gen ซึ่งได้ยกเครื่องเบื้องหลังใหม่ โดยเปลี่ยนจาก GAE(Google App Engine) ที่ใช้ตั้งแต่ปี 2017 มาเป็น Cloud Build, Cloud Run และ Eventarc

โดยการเปลี่ยนบริการที่อยู่เบื้องหลังใหม่นี้เอง ก็มาพร้อมกับจุดเด่นที่มาปิด pain point จาก 1st Gen และฟีเจอร์ใหม่ๆที่เพิ่มเข้ามา จะมีอะไรบ้างไปดูกันเลย!

1.1 Concurrency

ใน 1st Gen นั้นกฎของเรื่อง concurrency คือ 1 request/instance ซึ่งสมมติว่ามี 16 requests วิ่งมาหาฟังก์ชันที่เราสร้างไว้พร้อมๆกัน ตัว 1st Gen จะทำการสร้าง instance ขึ้นมา 16 ตัว คำถามคือแล้วมันมีข้อเสียตรงไหน? คำตอบคือ ตรงที่ทุกครั้งในการสร้าง instance มันจะต้องใช้เวลาในการ build ตัว instance ขึ้นมาจากทั้ง Linux, npm, Native libs และ Node.js ซึ่งทำให้การ response จะมี latency แฝงอยู่ หรือที่เราจะเรียกปัญหานี้ว่า Cold Start

แต่ใน 2nd Gen ปัญหานี้ได้หมดไปแล้ว เนื่องจาก 1 instance รองรับได้หลาย request โดยค่าเริ่มต้นจะอยู่ที่ 80 request/instance แต่เราก็สามารถปรับแต่งเองได้ตั้งแต่ 1–1,000 request/instance เลยทีเดียว ดังนั้นถ้าจำนวน concurrency ไม่เกินจากที่กำหนด ก็จะไม่มีการสร้าง instance ใหม่นั่นเอง

1.2 Cost Saving

เรื่องถัดมาคือเรื่องเงินๆทองๆ ซึ่งถือเป็นเรื่องใหญ่ของพวกเรา ^^ โดยผมจะขอเปรียบเทียบการคิดค่าบริการผ่านตัวอย่างต่อไปนี้ สมมติว่าฟังก์ชันที่สร้างจาก 1st Gen และ 2nd Gen มี 3 requests ที่จะต้องใช้เวลาในการประมวลผล 150ms วิ่งเข้าหาเหมือนๆกัน และแต่ละ request จะมีระยะห่างจากกัน 60ms ตามรูปด้านล่าง

  • ฟังก์ชันจาก 1st Gen จะทำการสร้าง instance ออกมา 3 ตัว โดยเวลาขั้นต่ำที่ Google จะคำนวนค่าใช้จ่ายจะอยู่ที่ 100ms ทำให้ 150ms ถูกปัดขึ้นเป็น 200ms ดังนั้น compute time จากทั้ง 3 requests จึงมีผลรวม 600ms
  • ฟังก์ชันจาก 2nd Gen จะทำการสร้าง instance ออกมาแค่ตัวเดียว โดยกว่าที่ request ตัวสุดท้ายจะทำงานเวลาก็จะผ่านไปแล้ว 120ms เมื่อมารวมกับระยะเวลาในการประมวลผลของ request ตัวสุดท้าย ก็จะเป็น 120 + 150 = 270ms และ Google จะคำนวนค่า compute time ขั้นต่ำที่ 100ms ผมรวมจึงเป็น 300ms ซึ่งประหยัดกว่า 1st Gen ถึง 2 เท่าในตัวอย่างนี้

1.3 New Instance Size

ด้วยการที่ 1 instance สามารถรองรับได้หลาย request แน่นอนว่าทรัพยากรก็จะถูกใช้เพิ่มขึ้นด้วยเช่นกัน ดังนั้นใน 2nd Gen ก็ให้เราสามารถปรับแต่ง memory และ CPU ของ instance ได้เพิ่มมากขึ้นด้วย โดย

  • Memory สามารถปรับแต่งได้ตั้งแต่ 128MB ไปจนถึง 32GB เลย
  • CPU สามารถปรับแต่งได้ตั้งแต่ 1 CPU ไปจนถึง 8 CPU

หมายเหตุ: การปรับ memory กับ CPU ที่สูงจะมีผลทำให้ค่าบริการสูงขึ้นตามไปด้วย

1.4 Request Timeout

ค่า Request Timeout จะเป็นค่าที่เราสามารถระบุเวลาสูงสุดที่จะให้ฟังก์ชันทำงาน โดยหากการทำงานของฟังก์ชันเกินเวลาไป ก็จะตีเป็น error timeout กลับไป โดยค่าเริ่มต้นของ request timeout ในแต่ละฟังก์ชันคือ 60s

  • 1st Gen สามารถปรับแต่งค่า request timeout ได้ตั้งแต่ 1s ถึง 9mins ทั้งฟังก์ชันแบบ Event triggers และ HTTP Requests
  • 2nd Gen สามารถปรับแต่งค่า request timeout กับฟังก์ชันแบบ HTTP Requests ได้ตั้งแต่ 1s ถึง 60mins โดยที่แบบ Event triggers จะเหมือน 1st Gen

1.5 New Language Support

ในตอนเปิดตัวในปี 2017 ตัว Cloud Functions นั้นรองรับเฉพาะ Node.js ซึ่งในปีถัดมาก็มีการรองรับ TypeScript เพิ่มเข้ามา จนกระทั่งใน 2nd Gen ที่เพิ่งเปิดตัวนี้เองที่ Cloud Functions เปิดตัวภาษาที่รองรับภาษาใหม่ นั่นก็คือ Python ภาษาที่มีคนทั่วโลกกว่า 17 ล้านเขียนกัน คราวนี้ใครอยากใช้พวก lib หรือ framework เกี่ยวกับ ML เช่น PyTorch ก็จัดไปได้เลย

1.6 Firebase Alert Events

Cloud Functions 2nd Gen มีการ integrate ร่วมกับบริการอีก 3 ตัวใน Firebase สำหรับการแจ้งเตือนทีมนักพัฒนา

  • Crashlytics สามารถเขียนฟังก์ชันไปเฝ้าดู crash ประเภทต่างๆที่เกิดขึ้นในแอป
  • Performance Monitoring สามารถเขียนฟังก์ชันไปเฝ้าดูประสิทธิ์ภาพของแอปหากเกิน threshold ที่กำหนด
  • App Distribution สามารถเขียนฟังก์ชันไปเฝ้าดู feedback ที่ tester ส่งมา หรือดูว่ามี iOS device ใหม่ register เข้ามา

1.7 Custom Event

หนึ่งในบริการของ Firebase ที่อำนวยความสะดวกให้นักพัฒนามากที่สุดตัวหนึ่ง ก็คือ Firebase Extensions ที่เป็น pre-package solution ให้นักพัฒนาสามารถ plug & play ได้ง่าย ซึ่งใน 2nd Gen ก็มีฟีเจอร์ให้เราสามารถไปคอยเฝ้าดูการทำงานของ extension บางตัวได้ เช่น Resize images หรือ Stripe เป็นต้น เพื่อที่จะให้ฟังก์ชันของเราทำงานเมื่อเกิดเหตุการณ์ต่างๆใน extension เช่น เมื่อ resize รูปเสร็จให้ฟังก์ชันเราส่งรูปที่ resize ไปให้เพื่อนเป็นต้น

1.8 Blocking Functions

ด้วยความร่วมมือของ Cloud Functions 2nd Gen, Firebase Authentication และ Google Cloud Identity ตอนนี้เรามี Blocking functions ที่ให้เราสามารถสร้างฟังก์ชันไปคั่นในกระบวนการ sign-up และ sign-in ของ Firebase Auth ได้ โดยตัวอย่างคือก่อนที่ผู้ใช้จะ sign-up สำเร็จเราจะตรวจสอบอีเมลของเขาก่อน ถ้าไม่ใช่ domain ที่เราต้องการก็สามารถปฏิเสธการ sign-up ครั้งนี้ได้

import { beforeUserCreated } from "firebase-functions/v2/identity";

export const blockauth = beforeUserCreated((event) => {
const user = event.data;
// Ensure only google.com emails can log into the changelog app
if (!user?.email?.includes('@google.com')) {
throw new HttpsError(
"permission-denied",
"Only @google.com are allowed to register.");
}
});

1.9 Task Queue Functions

ใครที่มี job ที่ต้องใช้เวลา run นานๆเจอเคส timeout บ้าง memory limit บ้าง หรือใครที่ยิง API ไปแล้วติด Rate limit ต้องชอบสิ่งนี้ เพราะ Cloud Functions 2nd Gen จับมือกับ Google Cloud Tasks ออกฟีเจอร์ Task Queue Functions ที่ให้นักพัฒนาสามารถเขียนโปรแกรมเพื่อ enqueue งาน โดยสามารถกำหนด rate limit ได้กำหนดการ retry ได้อีกด้วย

1.10 New Environment Configuration

นอกจากไฟล์ .env และ Cloud Secret Manager ที่นักพัฒนาน่าจะเคยใช้กันแล้วใน 1st Gen ใน 2nd จะมีตัว Parameterized Config เพิ่มเข้ามาอีกตัว

โดย Parameterized Config จะให้เราระบุ key และประเภทของ value ลงในโค้ด แต่จะไม่มีการระบุ value ลงไป โดย value จะถูกระบุครั้งแรกที่มีการ deploy ฟังก์ชันผ่าน command line เท่านั้น ซึ่งก็จะปลอดภัยมากขึ้น แถม param แต่ละตัวที่เรากำหนด เราสามารถระบุค่า default ให้ได้ แต่ทำการ validate ตัว value ที่นักพัฒนากรอกมาตอน deploy ได้อีกด้วย

const { onRequest } = require("firebase-functions/v2/https");
const { defineString, defineInt, defineSecret } = require("firebase-functions/params");

const welcomeMessage = defineString("WELCOME_MESSAGE");
const concurrencyConfig = defineInt("CONCURRENCY", { default: 80 });
const apiKey = defineSecret("API_KEY");

exports.f2 = onRequest({secrets: [apiKey], concurrency: concurrencyConfig}, (req, res) => {
const sampleApiKey = apiKey.value();
res.send(`${welcomeMessage.value()}! I am a function.`);
});

11. Built-in CORS

ใน 1st Gen การจะกำหนดเรื่อง CORS ว่าให้ domain ไหนเรียก API เราได้บ้างนี่จะต้องไปดึง dependency จาก third-party เข้ามา แล้วเขียนโค้ดโดยเอา cors มาคลุมโค้ดเราอีกท ซึ่งมันแอบขัดใจเล็กๆ แต่ใน 2nd Gen นี่สบายเลย เพราะเขา built-in ตัว CORS มาให้แล้ว ซึ่งวิธีเรียกใช้ก็ง่ายๆแบบด้านล่างนี้ครับ

const { onRequest } = require("firebase-functions/v2/https");

// Allow all origins
exports.f1 = onRequest({ cors: true }, (req, res) => {
res.send("Hello from Firebase!");
});

const origins = [
'http://localhost:5000',
'https://localhost:4000'
];

// Allow specific origins
exports.f2 = onRequest({ cors: origins }, (req, res) => {
res.send("Hello from Firebase!");
});

12. Gloal Runtime Options

สำหรับคนที่มีประสบการณ์ในการสร้างฟังก์ชันใน 1st Gen มาแล้ว น่าจะรู้จักกับ Runtime Options ที่ให้เรากำหนด option ต่างๆให้กับฟังก์ชันเรา เช่น region ที่ต้องการ deploy ไปลง, memory หรือ timeoutSeconds เป็นต้น ซึ่งใน 1st Gen หากเรามีหลายๆฟังก์ชัน และเราต้องการให้ runtime options เหมือนๆกัน เราก็ต้องไปกำหนดทุกฟังก์ชันเอง เช่น

const functions = require("firebase-functions/v1");

exports.f1 = functions.runWith({ memory: "1GB" }).https.onRequest((req, res) => {
res.send("Hello from Firebase!");
});

exports.f2 = functions.runWith({ memory: "1GB" }).https.onRequest((req, res) => {
res.send("Hello from Firebase!");
});

ซึ่งมันก็ดูเป็นงานที่ซ้ำซ้อนใช่ไหม แต่ใน 2nd Gen ปัญหานี้จะหมดไปด้วย Global Runtime Options ที่ให้เราสามารถกำหนด option ต่างๆไว้ที่ส่วนกลาง และทุกฟังก์ชันก็จะได้รับอนิสงส์ไปด้วยอัตโนมัติ คือดีย์!

const { onRequest } = require("firebase-functions/v2/https");
const { setGlobalOptions } = require("firebase-functions/v2");

setGlobalOptions({
region: "asia-southeast1",
memory: "1GB",
concurrency: 40
});

exports.f1 = onRequest((req, res) => {
res.send("Hello from Firebase!");
})

exports.f2 = onRequest((req, res) => {
res.send("Hello from Firebase!");
})

หมายเหตุ: กรณีที่ต้องการให้ฟังก์ชันใดมีการกำหนดค่า Runtime Options ที่แตกต่างก็ยังสามารถไปกำหนดค่าตรงๆแบบในข้อ 11.1 ได้ด้วย

2. วิธีติดตั้ง Cloud Functions for Firebase

2.1 สร้างโปรเจคใน Firebase

ใครที่มีโปรเจคกับ Firebase อยู่แล้วให้ข้ามขั้นตอนนี้ไปได้เลย ส่วนใครที่ยังไม่เคยมีหรือต้องการสร้างใหม่ให้ไปที่ Firebase Console จากนั้นกด Add project ระบุรายละเอียดต่างๆแล้วกด Create project

เมื่อกดเข้าไปในโปรเจคที่เราสร้าง สิ่งที่แรกที่ต้องทำคือ…ให้ไปเปลี่ยนแพลนจาก Spark เป็นเป็น Blaze(Pay as you go) ก่อน เนื่องจาก Cloud Functions for Firebase มีเงื่อนไขว่า หากต้องการ deploy ฟังก์ชันขึ้น production จำเป็นจะต้องใช้แพลนนี้

การเปลี่ยนมาใช้ Blaze plan นักพัฒนาจะได้โค้วต้าในการเรียกใช้งานฟังก์ชัน ฟรี 2,000,000 requests/เดือน

2.2 ติดตั้ง Node.js และ npm

ใครที่มีพร้อมทั้ง Node.js และ npm ในเครื่องแล้วให้ข้ามขั้นตอนนี้ไปได้เลย หรือตรวจสอบให้แน่ใจอีกครั้งผ่าน command line

node --version // ปัจจุบัน Cloud Functions รองรับเวอร์ชัน 14, 16, 18 และ 20
npm --version

ส่วนใครที่ยังไม่ได้ลง หรือไม่พบเลขเวอร์ชัน ให้ไปที่ https://nodejs.org ดาวน์โหลดและติดตั้ง Node.js ตามแต่ละ OS ที่เราใช้งานให้เรียบร้อย (การติดตั้ง Node.js จะได้ npm มาด้วย)

2.3 ติดตั้ง Firebase CLI

การ deploy ฟังก์ชันใน Cloud Functions for Firebase จะต้องทำผ่าน Firebase CLI ดังนั้นให้เราติดตั้งตัว CLI ใน command line ด้วยคำสั่ง

npm install -g firebase-tools

วิธีตรวจสอบว่าเราติดตั้ง Firebase CLI เรียบร้อยแล้ว ให้ใช้คำสั่งด้านล่างนี้ ซึ่งถ้าเห็นตัวเลขเวอร์ชันก็คือ ผ่าน!

firebase --version

2.4 Initial โปรเจค

เราจะมายืนยันตัวตน เพื่อเข้าถึงโปรเจคใน Firebase ของเรากัน โดยให้ run คำสั่งด้านล่างนี้ใน command line แล้วจะมี browser เด้งมาให้เรา login ก็ให้เรา login ด้วย account ที่ใช้สร้างโปรเจคใน Firebase ไปก่อนหน้านี้

firebase login

ถัดไปให้สร้างโฟลเดอร์ขึ้นมา(ในตัวอย่างนี้ชื่อ bot) แล้วให้เข้าไปในนั้น

mkdir bot
cd bot

แล้วให้ init ตัว Cloud Functions for Firebase ด้วยคำสั่ง

firebase init functions

จะเจอหน้าตาแบบด้านล่างนี้ ก็ให้เลือก Use an existing project แล้วเลือกโปรเจคที่เราสร้างไว้

จากนั้นจะมีคำถามมาอีก 3 คำถามคือ

  • จะใช้ภาษาอะไรในการพัฒนา โดยมี 3 ภาษาให้เลือก ได้แก่ JavaScript, TypeScript หรือ Python (ตัวอย่างในบทความจะใช้ JavaScript)
  • จะใช้ ESLint เพื่อตรวจสอบ bug และ code style ไหม (optional)
  • จะติดตั้ง dependencies ทันทีเลยไหม (จัดไปอย่าให้เสีย)

เพียงเท่านี้ก็ถือว่าเสร็จสิ้นขั้นตอนการ initial ละ โดยโครงสร้างของโปรเจคที่เราได้จะมีหน้าตาแบบนี้

/bot
+- .firebaserc # Hidden file that helps you quickly switch between projects with `firebase use`
|
+- firebase.json # Describes properties for your project
|
+- functions/ # Directory containing all your functions code
|
+- .eslintrc.json # Optional file containing rules for JavaScript linting.
|
+- package.json # npm package file describing your Cloud Functions code
|
+- index.js # Main source file for your Cloud Functions code
|
+- node_modules/ # Directory where your dependencies (declared in package.json) are installed

3. ลองสร้างฟังก์ชัน HTTP Requests กับ Event Triggers ให้ทำงานร่วมกัน

3.1 สร้างฟังก์ชันสำหรับ Write และ Update ค่าใน Firestore

เริ่มจากไปเปิดไฟล์ /functions/index.js แล้วให้ import ตัว dependency ของ Cloud Functions 2nd Gen, Firestore และ Firebase Admin เข้ามา

const {onRequest} = require("firebase-functions/v2/https");
const {onDocumentCreated} = require("firebase-functions/v2/firestore");

const {initializeApp} = require("firebase-admin/app");
const {getFirestore} = require("firebase-admin/firestore");
initializeApp();

ถัดไปให้สร้างฟังก์ชัน addmessage() ที่เป็นแบบ HTTP Requests โดยโค้ดภายในจะมีการรับ query param ชื่อ text แล้วเอาไป write ลง Firestore ที่ messages/original จากนั้นก็ให้พ่น JSON ซึ่งเป็น id ของ document ออกมา

exports.addmessage = onRequest(async (req, res) => {
const original = req.query.text;
const writeResult = await getFirestore().collection("messages").add({original: original});
res.json({result: `Message with ID: ${writeResult.id} added.`});
});

ถัดไปให้สร้างฟังก์ชัน makeuppercase() ที่เป็นแบบ Firebase trigger โดยการทำงานของฟังก์ชันนี้คือจะเฝ้าดู document ที่ถูกสร้างใหม่ขึ้นมา ซึ่งเมื่อมี doument ถูกสร้างใหม่จะส่งข้อมูลของ document นั้นมาที่ฟังก์ชันนี้ แล้วเราก็จะเอา value ที่อยู่ใน original ออกมา เข้าฟังก์ชัน toUpperCase() เพื่อทำให้ตัวหนังสือกลายเป็นพิมพ์ใหญ่ทั้งหมด จากนั้นก็ write กลับไปที่ Firestore

exports.makeuppercase = onDocumentCreated("/messages/{documentId}", (event) => {
const original = event.data.data().original;
const uppercase = original.toUpperCase();
return event.data.ref.set({uppercase}, {merge: true});
});

3.2 Deploy และทดลองเรียกฟังก์ชัน

วิธีการ deploy ให้เราเปิด command line แล้วเข้าไปยังโฟลเดอร์ /functions ในโปรเจค จากนั้นให้ใช้คำสั่ง

firebase deploy --only functions

ซึ่งเมื่อ deploy เสร็จแล้ว ให้เราเข้าไปที่ Firebase console แล้วเลือกโปรเจคที่เราสร้าง จากนั้นให้คลิกเลือกเมนู Build > Functions เราก็จะเห็นฟังก์ชันที่เรา deploy ไปตรงนั้น

จากรูปเราจะ copy ตัว Endpoint URL จากฟังก์ชันที่เป็น HTTP Requests ออกมาเพื่อแล้วนำไปเปิดบน browser เพื่อทดสอบกัน

ซึ่งเมื่อเราเข้าไปดูใน Firestore ก็จะพบข้อมูลทั้งแบบ oginial และ uppercase

หมายเหตุ

  • กรณีที่นำ Endpoint URL ที่ได้จากฟังก์ชันแบบ HTTP Requests ไปเปิด แล้วเจอว่าติด permission ให้ทำตามลิงค์นี้ เพื่อเปิดสิทธิ์ให้ทุกคนสามารถเปิด
  • การจะใช้งาน Firestore ครั้งแรก จะต้องเข้าไปเลือก location ของ Firestore ใน Firebase console ก่อน โดยคลิกเมนู Build > Firestore Database

สรุป

จากตัวอย่างในข้อ 3 น่าจะทำให้ผู้อ่านทุกท่านเห็นภาพในการสร้างฟังก์ชันทั้งแบบ HTTP Requests และ Event Triggers รวมถึงการทำงานร่วมกันได้ชัดเจนมากขึ้น

หวังว่าบทความนี้จะทำให้ผู้อ่านทุกท่านได้รู้จัก Cloud Functions for Firebase และเกิดไอเดียในนำมันไปพัฒนาบริการฝั่งหลังบ้านเพื่อเชื่อมกับ Client ในแพลทฟอร์มต่างๆนะครับ

สุดท้ายนี้ เพื่อไม่ให้พลาดข่าวสารเกี่ยวกับ Firebase ก็ฝากติดตามเพจ Firebase Thailand ไว้ หรือถ้าใครอยากแชร์ความรู้ สอบถามเกี่ยวกับ Firebase ก็ไปโพสถามกันได้ที่ Firebase Developer Group Thailand ได้นะครับ แล้วพบกันใหม่ในบทความถัดไป สวัสดีครับ

--

--

Jirawatee
Firebase Thailand

Technology Evangelist at LINE Thailand / Google Developer Expert in Firebase