เกี่ยวกับ Codelab นี้
1 ภาพรวม
ในโค้ดแล็บนี้ คุณจะได้เรียนรู้วิธีใช้ Cloud Functions for Firebase เพื่อเพิ่มฟังก์ชันการทำงานในเว็บแอปแชทด้วยการส่งการแจ้งเตือนไปยังผู้ใช้แอปแชท
สิ่งที่คุณจะได้เรียนรู้
- สร้าง Google Cloud Functions โดยใช้ Firebase SDK
- ทริกเกอร์ Cloud Functions ตามเหตุการณ์ของ Auth, Cloud Storage และ Cloud Firestore
- เพิ่มการรองรับ Firebase Cloud Messaging ลงในเว็บแอป
สิ่งที่ต้องมี
- บัตรเครดิต Cloud Functions for Firebase ต้องใช้แพ็กเกจ Firebase Blaze ซึ่งหมายความว่าคุณจะต้องเปิดใช้การเรียกเก็บเงินในโปรเจ็กต์ Firebase โดยใช้บัตรเครดิต
- IDE/เครื่องมือแก้ไขข้อความที่คุณเลือก เช่น WebStorm, Atom หรือ Sublime
- เทอร์มินัลสำหรับเรียกใช้คำสั่งเชลล์โดยติดตั้ง NodeJS v9 แล้ว
- เบราว์เซอร์ เช่น Chrome
- โค้ดตัวอย่าง โปรดดูขั้นตอนถัดไป
2 รับโค้ดตัวอย่าง
โคลนที่เก็บ GitHub จากบรรทัดคำสั่ง
git clone https://github.com/firebase/friendlychat
นําเข้าแอปเริ่มต้น
ใช้ IDE เปิดหรือนําเข้าไดเรกทอรี cloud-functions-start
จากไดเรกทอรีโค้ดตัวอย่าง ไดเรกทอรีนี้มีโค้ดเริ่มต้นสําหรับโค้ดแล็บ ซึ่งประกอบด้วยเว็บแอป Chat ที่ใช้งานได้อย่างเต็มรูปแบบ
3 สร้างโปรเจ็กต์ Firebase และตั้งค่าแอป
สร้างโปรเจ็กต์
ในคอนโซล Firebase ให้คลิกเพิ่มโปรเจ็กต์ แล้วตั้งชื่อว่า FriendlyChat
คลิกสร้างโปรเจ็กต์
อัปเกรดเป็นแพ็กเกจ Blaze
หากต้องการใช้ Cloud Functions for Firebase และ Cloud Storage for Firebase โปรเจ็กต์ Firebase ของคุณต้องใช้แพ็กเกจราคาแบบจ่ายเมื่อใช้ (Blaze) ซึ่งหมายความว่าโปรเจ็กต์ต้องลิงก์กับบัญชีการเรียกเก็บเงินระบบคลาวด์
- บัญชีการเรียกเก็บเงินระบบคลาวด์ต้องมีวิธีการชำระเงิน เช่น บัตรเครดิต
- หากคุณเพิ่งเริ่มใช้ Firebase และ Google Cloud ให้ตรวจสอบว่าคุณมีสิทธิ์รับเครดิตมูลค่า$300 และบัญชีการเรียกเก็บเงินระบบคลาวด์แบบทดลองใช้ฟรีหรือไม่
- หากคุณทำ Codelab นี้เป็นส่วนหนึ่งของกิจกรรม โปรดสอบถามผู้จัดว่ามีเครดิต Cloud เหลืออยู่ไหม
หากไม่มีสิทธิ์เข้าถึงบัตรเครดิตหรือไม่สะดวกที่จะใช้แพ็กเกจราคา Blaze ต่อไป ให้ลองใช้ชุดโปรแกรมจำลอง Firebase ซึ่งจะช่วยให้คุณจำลอง Cloud Functions ได้ฟรีบนเครื่องของคุณ
โปรเจ็กต์ Firebase ทั้งหมด รวมถึงโปรเจ็กต์ในแพ็กเกจราคา Blaze จะยังคงมีสิทธิ์เข้าถึงโควต้าการใช้งานแบบไม่มีค่าใช้จ่ายสำหรับ Cloud Functions ขั้นตอนที่ระบุไว้ในโค้ดแล็บนี้จะอยู่ในขีดจํากัดการใช้งานของระดับฟรี อย่างไรก็ตาม คุณจะเห็นการเรียกเก็บเงินเล็กน้อย (ประมาณ $0.03) จาก Cloud Storage ซึ่งใช้เพื่อโฮสต์รูปภาพบิลด์ Cloud Functions
หากต้องการอัปเกรดโปรเจ็กต์เป็นแพ็กเกจ Blaze ให้ทำตามขั้นตอนต่อไปนี้
- ในคอนโซล Firebase ให้เลือกอัปเกรดแพ็กเกจ
- เลือกแพ็กเกจ Blaze ทำตามวิธีการบนหน้าจอเพื่อลิงก์บัญชีสำหรับการเรียกเก็บเงินใน Cloud กับโปรเจ็กต์
หากจำเป็นต้องสร้างบัญชีสำหรับการเรียกเก็บเงินใน Cloud เป็นส่วนหนึ่งของการอัปเกรดนี้ คุณอาจต้องกลับไปที่ขั้นตอนการอัปเกรดในคอนโซล Firebase เพื่อดำเนินการอัปเกรดให้เสร็จสมบูรณ์
เปิดใช้ Google Auth
เราจะใช้การตรวจสอบสิทธิ์ของ Google ซึ่งต้องเปิดใช้เพื่อให้ผู้ใช้ลงชื่อเข้าใช้แอปได้
ใน Firebase Console ให้เปิดส่วนบิลด์ > การตรวจสอบสิทธิ์ > แท็บวิธีการลงชื่อเข้าใช้ (หรือคลิกที่นี่เพื่อไปที่ส่วนดังกล่าว) จากนั้นเปิดใช้ผู้ให้บริการลงชื่อเข้าใช้ Google แล้วคลิกบันทึก ซึ่งจะช่วยให้ผู้ใช้ลงชื่อเข้าใช้เว็บแอปด้วยบัญชี Google ได้
นอกจากนี้ คุณยังตั้งชื่อแอปที่แสดงต่อสาธารณะเป็น Friendly Chat ได้ด้วย
ตั้งค่า Cloud Storage for Firebase
แอปใช้ Cloud Storage เพื่ออัปโหลดรูปภาพ
วิธีตั้งค่า Cloud Storage for Firebase ในโปรเจ็กต์ Firebase มีดังนี้
- ในแผงด้านซ้ายของคอนโซล Firebase ให้ขยายบิลด์ แล้วเลือกพื้นที่เก็บข้อมูล
- คลิกเริ่มต้นใช้งาน
- เลือกตำแหน่งสำหรับที่เก็บข้อมูล Storage เริ่มต้น
ที่เก็บข้อมูลในUS-WEST1
,US-CENTRAL1
และUS-EAST1
สามารถใช้แพ็กเกจ"ฟรีตลอด" สำหรับ Google Cloud Storage ที่เก็บข้อมูลในตำแหน่งอื่นๆ ทั้งหมดจะเป็นไปตามราคาและการใช้งาน Google Cloud Storage - คลิกเริ่มในโหมดทดสอบ อ่านข้อจำกัดความรับผิดเกี่ยวกับกฎความปลอดภัย
อย่าเผยแพร่หรือแสดงแอปต่อสาธารณะโดยไม่เพิ่มกฎความปลอดภัยสำหรับที่เก็บข้อมูล - คลิกสร้าง
เพิ่มเว็บแอป
ในคอนโซล Firebase ให้เพิ่มเว็บแอป โดยไปที่การตั้งค่าโปรเจ็กต์ แล้วเลื่อนลงไปที่เพิ่มแอป เลือกเว็บเป็นแพลตฟอร์มแล้วเลือกช่องสำหรับตั้งค่า Firebase Hosting จากนั้นลงทะเบียนแอปแล้วคลิกถัดไปเพื่อไปยังขั้นตอนที่เหลือ แล้วคลิกไปที่คอนโซลเป็นขั้นตอนสุดท้าย
4 ติดตั้งอินเทอร์เฟซบรรทัดคำสั่ง Firebase
อินเทอร์เฟซบรรทัดคำสั่ง (CLI) ของ Firebase จะช่วยให้คุณแสดงเว็บแอปในเครื่องและทำให้เว็บแอปและ Cloud Functions ใช้งานได้
หากต้องการติดตั้งหรืออัปเกรด CLI ให้เรียกใช้คำสั่ง npm ต่อไปนี้
npm -g install firebase-tools
หากต้องการยืนยันว่าติดตั้ง CLI อย่างถูกต้องแล้ว ให้เปิดคอนโซลแล้วเรียกใช้คำสั่งต่อไปนี้
firebase --version
ตรวจสอบว่า Firebase CLI เป็นเวอร์ชันที่สูงกว่า 4.0.0 เพื่อให้มีฟีเจอร์ล่าสุดทั้งหมดที่จำเป็นสำหรับ Cloud Functions หากไม่ ให้เรียกใช้ npm install -g firebase-tools
เพื่ออัปเกรดตามที่แสดงด้านบน
ให้สิทธิ์ Firebase CLI โดยเรียกใช้คำสั่งต่อไปนี้
firebase login
ตรวจสอบว่าคุณอยู่ในไดเรกทอรี cloud-functions-start
จากนั้นตั้งค่า Firebase CLI เพื่อใช้โปรเจ็กต์ Firebase โดยทำดังนี้
firebase use --add
ถัดไป ให้เลือกรหัสโปรเจ็กต์แล้วทําตามวิธีการ เมื่อได้รับข้อความแจ้ง คุณจะเลือกอีเมลแทนได้ เช่น codelab
5 ติดตั้งใช้งานและเรียกใช้เว็บแอป
เมื่อนำเข้าและกำหนดค่าโปรเจ็กต์แล้ว คุณก็พร้อมเรียกใช้เว็บแอปเป็นครั้งแรก เปิดหน้าต่างเทอร์มินัล ไปที่โฟลเดอร์ cloud-functions-start
แล้วทำให้เว็บแอปใช้งานได้ในโฮสติ้ง Firebase โดยใช้คำสั่งต่อไปนี้
firebase deploy --except functions
คุณควรเห็นเอาต์พุตคอนโซลดังต่อไปนี้
i deploying database, storage, hosting
✔ database: rules ready to deploy.
i storage: checking rules for compilation errors...
✔ storage: rules file compiled successfully
i hosting: preparing ./ directory for upload...
✔ hosting: ./ folder uploaded successfully
✔ storage: rules file compiled successfully
✔ hosting: 8 files uploaded successfully
i starting release process (may take several minutes)...
✔ Deploy complete!
Project Console: https://console.firebase.google.com/project/friendlychat-1234/overview
Hosting URL: https://friendlychat-1234.firebaseapp.com
เปิดเว็บแอป
บรรทัดสุดท้ายควรแสดง URL โฮสติ้ง ตอนนี้เว็บแอปควรแสดงจาก URL นี้ ซึ่งควรอยู่ในรูปแบบ https://<project-id>.firebaseapp.com ให้เปิด URL ดังกล่าว คุณควรเห็น UI ที่ใช้งานได้ของแอปแชท
ลงชื่อเข้าใช้แอปโดยใช้ปุ่มลงชื่อเข้าใช้ด้วย Google แล้วเพิ่มข้อความและโพสต์รูปภาพได้ตามต้องการ
หากคุณลงชื่อเข้าใช้แอปเป็นครั้งแรกในเบราว์เซอร์ใหม่ โปรดตรวจสอบว่าคุณอนุญาตการแจ้งเตือนเมื่อได้รับข้อความแจ้ง
เราจะต้องเปิดใช้การแจ้งเตือนในภายหลัง
หากคลิกบล็อกโดยไม่ตั้งใจ คุณสามารถเปลี่ยนการตั้งค่านี้ได้โดยคลิกปุ่ม🔒 ปลอดภัยทางด้านซ้ายของ URL ในแถบ Omnibar ของ Chrome แล้วสลับแถบข้างการแจ้งเตือน
ตอนนี้เราจะเพิ่มฟังก์ชันบางอย่างโดยใช้ Firebase SDK สําหรับ Cloud Functions
6 ไดเรกทอรีฟังก์ชัน
Cloud Functions ช่วยให้คุณมีโค้ดที่ทำงานในระบบคลาวด์ได้ง่ายๆ โดยไม่ต้องตั้งค่าเซิร์ฟเวอร์ เราจะอธิบายวิธีสร้างฟังก์ชันที่ตอบสนองต่อเหตุการณ์ในฐานข้อมูล Firebase Auth, Cloud Storage และ Firebase Firestore มาเริ่มกันที่การตรวจสอบสิทธิ์
เมื่อใช้ Firebase SDK สําหรับ Cloud Functions โค้ดฟังก์ชันจะอยู่ภายใต้ไดเรกทอรี functions
(โดยค่าเริ่มต้น) โค้ดฟังก์ชันของคุณเป็นแอป Node.js ด้วย จึงต้องมี package.json
ที่ระบุข้อมูลบางอย่างเกี่ยวกับแอปและแสดงรายการทรัพยากร Dependency
เราได้สร้างไฟล์ functions/index.js
ไว้ให้แล้วสำหรับใส่โค้ดของคุณ คุณสามารถตรวจสอบไฟล์นี้ก่อนดำเนินการต่อได้
cd functions
ls
หากคุณไม่คุ้นเคยกับ Node.js คุณควรดูข้อมูลเพิ่มเติมเกี่ยวกับภาษานี้ก่อนทำโค้ดแล็บต่อ
ไฟล์ package.json
แสดงรายการทรัพยากรที่ต้องพึ่งพา 2 รายการอยู่แล้ว ได้แก่ Firebase SDK สําหรับ Cloud Functions และ Firebase Admin SDK หากต้องการติดตั้งในเครื่อง ให้ไปที่โฟลเดอร์ functions
แล้วเรียกใช้คำสั่งต่อไปนี้
npm install
มาดูไฟล์ index.js
กัน
index.js
/**
* Copyright 2017 Google Inc. All Rights Reserved.
* ...
*/
// TODO(DEVELOPER): Import the Cloud Functions for Firebase and the Firebase Admin modules here.
// TODO(DEVELOPER): Write the addWelcomeMessage Function here.
// TODO(DEVELOPER): Write the blurImages Function here.
// TODO(DEVELOPER): Write the sendNotification Function here.
เราจะนําเข้าโมดูลที่จําเป็น แล้วเขียนฟังก์ชัน 3 รายการแทน TODO มาเริ่มด้วยการนําเข้าโมดูล Node ที่จําเป็นกัน
7 นําเข้าโมดูล Cloud Functions และ Firebase Admin
คุณต้องใช้ 2 โมดูลในโค้ดแล็บนี้ โดย firebase-functions
ช่วยให้เขียนทริกเกอร์และบันทึกของ Cloud Functions ได้ ส่วน firebase-admin
ช่วยให้ใช้แพลตฟอร์ม Firebase ในเซิร์ฟเวอร์ที่มีสิทธิ์เข้าถึงระดับผู้ดูแลระบบเพื่อดำเนินการต่างๆ เช่น การเขียนลงใน Cloud Firestore หรือการส่งการแจ้งเตือน FCM ได้
ในไฟล์ index.js
ให้แทนที่ TODO
แรกด้วยข้อมูลต่อไปนี้
index.js
/**
* Copyright 2017 Google Inc. All Rights Reserved.
* ...
*/
// Import the Firebase SDK for Google Cloud Functions.
const functions = require('firebase-functions');
// Import and initialize the Firebase Admin SDK.
const admin = require('firebase-admin');
admin.initializeApp();
// TODO(DEVELOPER): Write the addWelcomeMessage Function here.
// TODO(DEVELOPER): Write the blurImages Function here.
// TODO(DEVELOPER): Write the sendNotification Function here.
Firebase Admin SDK สามารถกําหนดค่าโดยอัตโนมัติเมื่อติดตั้งใช้งานในสภาพแวดล้อม Cloud Functions หรือคอนเทนเนอร์ Google Cloud Platform อื่นๆ ซึ่งจะเกิดขึ้นเมื่อเราเรียกใช้ admin.initializeApp()
โดยไม่มีอาร์กิวเมนต์
ตอนนี้มาเพิ่มฟังก์ชันที่ทำงานเมื่อผู้ใช้ลงชื่อเข้าใช้แอปแชทเป็นครั้งแรก และเราจะเพิ่มข้อความแชทเพื่อต้อนรับผู้ใช้
8 ต้อนรับผู้ใช้ใหม่
โครงสร้างข้อความใน Chat
ระบบจะจัดเก็บข้อความที่โพสต์ไปยังฟีดแชทของ FriendlyChat ใน Cloud Firestore มาดูโครงสร้างข้อมูลที่ใช้สําหรับข้อความกัน โดยโพสต์ข้อความใหม่ในแชทว่า "Hello World" ดังนี้
ซึ่งควรปรากฏเป็น
ในคอนโซล Firebase ให้คลิกฐานข้อมูล Firestore ในส่วนสร้าง คุณควรเห็นคอลเล็กชันข้อความและเอกสาร 1 รายการที่มีข้อความที่คุณเขียน
ดังที่คุณเห็น ข้อความแชทจะจัดเก็บไว้ใน Cloud Firestore เป็นเอกสารที่มีการเพิ่มแอตทริบิวต์ name
, profilePicUrl
, text
และ timestamp
ลงในคอลเล็กชัน messages
การเพิ่มข้อความต้อนรับ
Cloud Function แรกจะเพิ่มข้อความต้อนรับผู้ใช้ใหม่ในแชท ในกรณีนี้ เราสามารถใช้ทริกเกอร์ functions.auth().onCreate
ซึ่งจะเรียกใช้ฟังก์ชันทุกครั้งที่ผู้ใช้ลงชื่อเข้าใช้แอป Firebase เป็นครั้งแรก เพิ่มฟังก์ชัน addWelcomeMessages
ลงในไฟล์ index.js
ดังนี้
index.js
// Adds a message that welcomes new users into the chat.
exports.addWelcomeMessages = functions.auth.user().onCreate(async (user) => {
functions.logger.log('A new user signed in for the first time.');
const fullName = user.displayName || 'Anonymous';
// Saves the new welcome message into the database
// which then displays it in the FriendlyChat clients.
await admin.firestore().collection('messages').add({
name: 'Firebase Bot',
profilePicUrl: '/images/firebase-logo.png', // Firebase logo
text: `${fullName} signed in for the first time! Welcome!`,
timestamp: admin.firestore.FieldValue.serverTimestamp(),
});
functions.logger.log('Welcome message written to database.');
});
การเพิ่มฟังก์ชันนี้ลงในออบเจ็กต์ exports
พิเศษเป็นวิธีที่ Node ทําให้ฟังก์ชันเข้าถึงได้นอกไฟล์ปัจจุบัน และจําเป็นสําหรับ Cloud Functions
ในฟังก์ชันด้านบน เราเพิ่มข้อความต้อนรับใหม่ซึ่งโพสต์โดย "Firebase Bot" ลงในรายการข้อความแชท เราดำเนินการนี้โดยใช้เมธอด add
ในคอลเล็กชัน messages
ใน Cloud Firestore ซึ่งเป็นที่เก็บข้อความของแชท
เนื่องจากการดำเนินการนี้เป็นการดำเนินการแบบไม่พร้อมกัน เราจึงต้องแสดงผล Promise ที่ระบุว่า Cloud Firestore เขียนข้อมูลเสร็จแล้วเมื่อใด เพื่อไม่ให้ Cloud Functions ทำงานเร็วเกินไป
ติดตั้งใช้งาน Cloud Functions
Cloud Functions จะทำงานหลังจากที่คุณทำให้ใช้งานได้แล้วเท่านั้น โดยให้เรียกใช้คำสั่งนี้ในบรรทัดคำสั่ง
firebase deploy --only functions
คุณควรเห็นเอาต์พุตคอนโซลดังต่อไปนี้
i deploying functions
i functions: ensuring necessary APIs are enabled...
⚠ functions: missing necessary APIs. Enabling now...
i env: ensuring necessary APIs are enabled...
⚠ env: missing necessary APIs. Enabling now...
i functions: waiting for APIs to activate...
i env: waiting for APIs to activate...
✔ env: all necessary APIs are enabled
✔ functions: all necessary APIs are enabled
i functions: preparing functions directory for uploading...
i functions: packaged functions (X.XX KB) for uploading
✔ functions: functions folder uploaded successfully
i starting release process (may take several minutes)...
i functions: creating function addWelcomeMessages...
✔ functions[addWelcomeMessages]: Successful create operation.
✔ functions: all functions deployed successfully!
✔ Deploy complete!
Project Console: https://console.firebase.google.com/project/friendlypchat-1234/overview
ทดสอบฟังก์ชัน
เมื่อติดตั้งใช้งานฟังก์ชันเรียบร้อยแล้ว คุณจะต้องมีผู้ใช้ที่ลงชื่อเข้าใช้เป็นครั้งแรก
- เปิดแอปในเบราว์เซอร์โดยใช้ URL โฮสติ้ง (ในรูปแบบ
https://<project-id>.firebaseapp.com
) - ผู้ใช้ใหม่จะลงชื่อเข้าใช้แอปเป็นครั้งแรกโดยใช้ปุ่มลงชื่อเข้าใช้
- หากลงชื่อเข้าใช้แอปแล้ว คุณสามารถเปิดการตรวจสอบสิทธิ์คอนโซล Firebase และลบบัญชีของคุณออกจากรายชื่อผู้ใช้ได้ จากนั้นลงชื่อเข้าใช้อีกครั้ง
- หลังจากลงชื่อเข้าใช้แล้ว ข้อความต้อนรับจะปรากฏขึ้นโดยอัตโนมัติ
9 การดูแลรูปภาพ
ผู้ใช้สามารถอัปโหลดรูปภาพทุกประเภทในแชท และการดูแลรูปภาพที่ไม่เหมาะสมเป็นสิ่งสําคัญเสมอ โดยเฉพาะอย่างยิ่งในแพลตฟอร์มโซเชียลแบบสาธารณะ ใน FriendlyChat รูปภาพที่เผยแพร่ในแชทจะจัดเก็บไว้ในที่เก็บข้อมูล Cloud Storage
Cloud Functions ช่วยให้คุณตรวจหาการอัปโหลดรูปภาพใหม่ได้โดยใช้ทริกเกอร์ functions.storage().onFinalize
ซึ่งจะทำงานทุกครั้งที่มีอัปโหลดหรือแก้ไขไฟล์ใหม่ใน Cloud Storage
เราจะดำเนินการตามกระบวนการต่อไปนี้เพื่อดูแลจัดการรูปภาพ
- ตรวจสอบว่ารูปภาพถูกแจ้งว่าไม่เหมาะสมสําหรับผู้ใหญ่หรือมีความรุนแรงหรือไม่โดยใช้ Cloud Vision API
- หากมีการแจ้งว่ารูปภาพไม่เหมาะสม ให้ดาวน์โหลดรูปภาพในอินสแตนซ์ Functions ที่ทำงานอยู่
- เบลอรูปภาพโดยใช้ ImageMagick
- อัปโหลดรูปภาพที่เบลอไปยัง Cloud Storage
เปิดใช้ Cloud Vision API
เนื่องจากเราจะใช้ Google Cloud Vision API ในฟังก์ชันนี้ คุณจึงต้องเปิดใช้ API ในโปรเจ็กต์ Firebase โปรดไปที่ลิงก์นี้ แล้วเลือกโปรเจ็กต์ Firebase เพื่อเปิดใช้ API
ติดตั้งข้อกําหนดเบื้องต้น
เราจะใช้ไลบรารีของไคลเอ็นต์ Google Cloud Vision สำหรับ Node.js อย่าง @google-cloud/vision เพื่อเรียกใช้รูปภาพผ่าน Cloud Vision API เพื่อตรวจหารูปภาพที่ไม่เหมาะสมในการดูแลเนื้อหา
หากต้องการติดตั้งแพ็กเกจนี้ลงในแอป Cloud Functions ให้เรียกใช้คำสั่ง npm install --save
ต่อไปนี้ ตรวจสอบว่าคุณดำเนินการนี้จากไดเรกทอรี functions
npm install --save @google-cloud/vision@2.4.0
ซึ่งจะติดตั้งแพ็กเกจในเครื่องและเพิ่มเป็นข้อกำหนดที่ประกาศไว้ในไฟล์ package.json
นําเข้าและกําหนดค่าทรัพยากร Dependency
หากต้องการนําเข้า Dependency ที่ติดตั้งไว้และโมดูลหลักของ Node.js บางรายการ (path
, os
และ fs
) ที่เราต้องใช้ในส่วนนี้ ให้เพิ่มบรรทัดต่อไปนี้ที่ด้านบนของไฟล์ index.js
index.js
const Vision = require('@google-cloud/vision');
const vision = new Vision.ImageAnnotatorClient();
const {promisify} = require('util');
const exec = promisify(require('child_process').exec);
const path = require('path');
const os = require('os');
const fs = require('fs');
เนื่องจากฟังก์ชันจะทำงานภายในสภาพแวดล้อม Google Cloud คุณจึงไม่จำเป็นต้องกำหนดค่าไลบรารี Cloud Storage และ Cloud Vision ระบบจะกำหนดค่าให้ใช้โปรเจ็กต์โดยอัตโนมัติ
การตรวจจับรูปภาพไม่เหมาะสม
คุณจะใช้ทริกเกอร์ functions.storage.onChange
Cloud Functions ซึ่งจะเรียกใช้โค้ดทันทีที่มีการสร้างหรือแก้ไขไฟล์หรือโฟลเดอร์ในที่เก็บข้อมูล Cloud Storage เพิ่มฟังก์ชัน blurOffensiveImages
ลงในไฟล์ index.js
index.js
// Checks if uploaded images are flagged as Adult or Violence and if so blurs them.
exports.blurOffensiveImages = functions.runWith({memory: '2GB'}).storage.object().onFinalize(
async (object) => {
const imageUri = `gs://${object.bucket}/${object.name}`;
// Check the image content using the Cloud Vision API.
const batchAnnotateImagesResponse = await vision.safeSearchDetection(imageUri);
const safeSearchResult = batchAnnotateImagesResponse[0].safeSearchAnnotation;
const Likelihood = Vision.protos.google.cloud.vision.v1.Likelihood;
if (Likelihood[safeSearchResult.adult] >= Likelihood.LIKELY ||
Likelihood[safeSearchResult.violence] >= Likelihood.LIKELY) {
functions.logger.log('The image', object.name, 'has been detected as inappropriate.');
return blurImage(object.name);
}
functions.logger.log('The image', object.name, 'has been detected as OK.');
});
โปรดทราบว่าเราได้เพิ่มการกำหนดค่าบางอย่างของอินสแตนซ์ Cloud Functions ที่จะเรียกใช้ฟังก์ชัน สำหรับ .runWith({memory: '2GB'})
เราจะขอให้อินสแตนซ์มีหน่วยความจำ 2 GB แทนค่าเริ่มต้น เนื่องจากฟังก์ชันนี้ใช้หน่วยความจำมาก
เมื่อทริกเกอร์ฟังก์ชัน ระบบจะเรียกใช้รูปภาพผ่าน Cloud Vision API เพื่อตรวจหาว่ามีการทำเครื่องหมายว่าไม่เหมาะสมกับผู้ใหญ่หรือมีความรุนแรงหรือไม่ หากระบบตรวจพบว่ารูปภาพไม่เหมาะสมตามเกณฑ์เหล่านี้ เราจะเบลอรูปภาพ ซึ่งจะดำเนินการในฟังก์ชัน blurImage
ดังที่เราจะได้เห็นในลำดับถัดไป
การเบลอรูปภาพ
เพิ่มฟังก์ชัน blurImage
ต่อไปนี้ในไฟล์ index.js
index.js
// Blurs the given image located in the given bucket using ImageMagick.
async function blurImage(filePath) {
const tempLocalFile = path.join(os.tmpdir(), path.basename(filePath));
const messageId = filePath.split(path.sep)[1];
const bucket = admin.storage().bucket();
// Download file from bucket.
await bucket.file(filePath).download({destination: tempLocalFile});
functions.logger.log('Image has been downloaded to', tempLocalFile);
// Blur the image using ImageMagick.
await exec(`convert "${tempLocalFile}" -channel RGBA -blur 0x24 "${tempLocalFile}"`);
functions.logger.log('Image has been blurred');
// Uploading the Blurred image back into the bucket.
await bucket.upload(tempLocalFile, {destination: filePath});
functions.logger.log('Blurred image has been uploaded to', filePath);
// Deleting the local file to free up disk space.
fs.unlinkSync(tempLocalFile);
functions.logger.log('Deleted local file.');
// Indicate that the message has been moderated.
await admin.firestore().collection('messages').doc(messageId).update({moderated: true});
functions.logger.log('Marked the image as moderated in the database.');
}
ในฟังก์ชันข้างต้น ระบบจะดาวน์โหลดไบนารีรูปภาพจาก Cloud Storage จากนั้นระบบจะเบลอรูปภาพโดยใช้เครื่องมือ convert
ของ ImageMagick และอัปโหลดเวอร์ชันเบลอลงในที่เก็บข้อมูลอีกครั้ง จากนั้นเราจะลบไฟล์ในอินสแตนซ์ Cloud Functions เพื่อเพิ่มพื้นที่ว่างในดิสก์ ซึ่งเราทําเช่นนี้เนื่องจากอินสแตนซ์ Cloud Functions เดียวกันนี้สามารถนำมาใช้ซ้ำได้ และหากไม่ล้างไฟล์ออก พื้นที่ในดิสก์อาจไม่เพียงพอ สุดท้าย เราจะเพิ่มบูลีนลงในข้อความแชทเพื่อระบุว่ารูปภาพได้รับการตรวจสอบแล้ว ซึ่งจะทริกเกอร์การรีเฟรชข้อความในไคลเอ็นต์
ทำให้ฟังก์ชันใช้งานได้
ฟังก์ชันจะทำงานหลังจากที่คุณทำให้ใช้งานได้แล้วเท่านั้น ในบรรทัดคำสั่ง ให้เรียกใช้ firebase deploy --only functions
ดังนี้
firebase deploy --only functions
คุณควรเห็นเอาต์พุตคอนโซลดังต่อไปนี้
i deploying functions
i functions: ensuring necessary APIs are enabled...
✔ functions: all necessary APIs are enabled
i functions: preparing functions directory for uploading...
i functions: packaged functions (X.XX KB) for uploading
✔ functions: functions folder uploaded successfully
i starting release process (may take several minutes)...
i functions: updating function addWelcomeMessages...
i functions: creating function blurOffensiveImages...
✔ functions[addWelcomeMessages]: Successful update operation.
✔ functions[blurOffensiveImages]: Successful create operation.
✔ functions: all functions deployed successfully!
✔ Deploy complete!
Project Console: https://console.firebase.google.com/project/friendlychat-1234/overview
ทดสอบฟังก์ชัน
เมื่อทำให้ฟังก์ชันใช้งานได้สําเร็จแล้ว ให้ทําดังนี้
- เปิดแอปในเบราว์เซอร์โดยใช้ URL โฮสติ้ง (ในรูปแบบ
https://<project-id>.firebaseapp.com
) - เมื่อลงชื่อเข้าใช้แอปแล้ว ให้อัปโหลดรูปภาพโดยทำดังนี้
- เลือกรูปภาพที่ไม่เหมาะสมที่สุดที่จะอัปโหลด (หรือจะใช้ซอมบี้กินเนื้อนี้ก็ได้) และหลังจากผ่านไป 2-3 นาที คุณควรเห็นโพสต์รีเฟรชด้วยรูปภาพที่เบลอ
10 การแจ้งเตือนข้อความใหม่
ในส่วนนี้ คุณจะเพิ่ม Cloud Function ที่ส่งการแจ้งเตือนไปยังผู้เข้าร่วมแชทเมื่อมีการส่งข้อความใหม่
เมื่อใช้ Firebase Cloud Messaging (FCM) คุณจะส่งการแจ้งเตือนไปยังผู้ใช้ในแพลตฟอร์มต่างๆ ได้อย่างน่าเชื่อถือ หากต้องการส่งการแจ้งเตือนถึงผู้ใช้ คุณต้องมีโทเค็นอุปกรณ์ FCM ของผู้ใช้ เว็บแอปแชทที่เราใช้อยู่จะรวบรวมโทเค็นอุปกรณ์จากผู้ใช้เมื่อเปิดแอปเป็นครั้งแรกในเบราว์เซอร์หรืออุปกรณ์เครื่องใหม่อยู่แล้ว ระบบจะจัดเก็บโทเค็นเหล่านี้ไว้ใน Cloud Firestore ในคอลเล็กชัน fcmTokens
หากต้องการดูวิธีรับโทเค็นอุปกรณ์ FCM ในเว็บแอป ให้ไปที่ Firebase Web Codelab
ส่งการแจ้งเตือน
หากต้องการตรวจหาเมื่อมีโพสต์ข้อความใหม่ คุณจะใช้functions.firestore.document().onCreate
ทริกเกอร์ Cloud Functions ซึ่งจะเรียกใช้โค้ดเมื่อสร้างออบเจ็กต์ใหม่ในเส้นทางที่ระบุของ Cloud Firestore เพิ่มฟังก์ชัน sendNotifications
ลงในไฟล์ index.js
index.js
// Sends a notifications to all users when a new message is posted.
exports.sendNotifications = functions.firestore.document('messages/{messageId}').onCreate(
async (snapshot) => {
// Notification details.
const text = snapshot.data().text;
const payload = {
notification: {
title: `${snapshot.data().name} posted ${text ? 'a message' : 'an image'}`,
body: text ? (text.length <= 100 ? text : text.substring(0, 97) + '...') : '',
icon: snapshot.data().profilePicUrl || '/images/profile_placeholder.png',
click_action: `https://${process.env.GCLOUD_PROJECT}.firebaseapp.com`,
}
};
// Get the list of device tokens.
const allTokens = await admin.firestore().collection('fcmTokens').get();
const tokens = [];
allTokens.forEach((tokenDoc) => {
tokens.push(tokenDoc.id);
});
if (tokens.length > 0) {
// Send notifications to all tokens.
const response = await admin.messaging().sendToDevice(tokens, payload);
await cleanupTokens(response, tokens);
functions.logger.log('Notifications have been sent and tokens cleaned up.');
}
});
ในฟังก์ชันด้านบน เรากำลังรวบรวมโทเค็นอุปกรณ์ของผู้ใช้ทั้งหมดจากฐานข้อมูล Cloud Firestore และส่งการแจ้งเตือนไปยังแต่ละรายการเหล่านี้โดยใช้ฟังก์ชัน admin.messaging().sendToDevice
ล้างข้อมูลโทเค็น
สุดท้าย เราต้องการนําโทเค็นที่ใช้ไม่ได้แล้วออก กรณีนี้เกิดขึ้นเมื่อเบราว์เซอร์หรืออุปกรณ์ไม่ได้ใช้โทเค็นที่เราเคยได้รับจากผู้ใช้แล้ว ตัวอย่างเช่น กรณีนี้จะเกิดขึ้นหากผู้ใช้เพิกถอนสิทธิ์การแจ้งเตือนสำหรับเซสชันเบราว์เซอร์ โดยให้เพิ่มฟังก์ชัน cleanupTokens
ต่อไปนี้ในไฟล์ index.js
index.js
// Cleans up the tokens that are no longer valid.
function cleanupTokens(response, tokens) {
// For each notification we check if there was an error.
const tokensDelete = [];
response.results.forEach((result, index) => {
const error = result.error;
if (error) {
functions.logger.error('Failure sending notification to', tokens[index], error);
// Cleanup the tokens that are not registered anymore.
if (error.code === 'messaging/invalid-registration-token' ||
error.code === 'messaging/registration-token-not-registered') {
const deleteTask = admin.firestore().collection('fcmTokens').doc(tokens[index]).delete();
tokensDelete.push(deleteTask);
}
}
});
return Promise.all(tokensDelete);
}
ทำให้ฟังก์ชันใช้งานได้
ฟังก์ชันจะทำงานหลังจากที่คุณทำให้ใช้งานได้แล้วเท่านั้น และหากต้องการทำให้ใช้งานได้ ให้เรียกใช้คำสั่งนี้ในบรรทัดคำสั่ง
firebase deploy --only functions
คุณควรเห็นเอาต์พุตคอนโซลดังต่อไปนี้
i deploying functions
i functions: ensuring necessary APIs are enabled...
✔ functions: all necessary APIs are enabled
i functions: preparing functions directory for uploading...
i functions: packaged functions (X.XX KB) for uploading
✔ functions: functions folder uploaded successfully
i starting release process (may take several minutes)...
i functions: updating function addWelcomeMessages...
i functions: updating function blurOffensiveImages...
i functions: creating function sendNotifications...
✔ functions[addWelcomeMessages]: Successful update operation.
✔ functions[blurOffensiveImages]: Successful updating operation.
✔ functions[sendNotifications]: Successful create operation.
✔ functions: all functions deployed successfully!
✔ Deploy complete!
Project Console: https://console.firebase.google.com/project/friendlychat-1234/overview
ทดสอบฟังก์ชัน
- เมื่อติดตั้งใช้งานฟังก์ชันเรียบร้อยแล้ว ให้เปิดแอปในเบราว์เซอร์โดยใช้ URL โฮสติ้ง (ในรูปแบบ
https://<project-id>.firebaseapp.com
) - หากคุณลงชื่อเข้าใช้แอปเป็นครั้งแรก โปรดอนุญาตให้แสดงการแจ้งเตือนเมื่อระบบขอ
- ปิดแท็บแอปแชทหรือแสดงแท็บอื่น: การแจ้งเตือนจะปรากฏขึ้นเฉพาะในกรณีที่แอปทำงานอยู่เบื้องหลัง หากต้องการดูวิธีรับข้อความขณะที่แอปอยู่ในเบื้องหน้า โปรดดูเอกสารประกอบของเรา
- ลงชื่อเข้าใช้แอปและโพสต์ข้อความโดยใช้เบราว์เซอร์อื่น (หรือหน้าต่างที่ไม่ระบุตัวตน) คุณควรเห็นการแจ้งเตือนที่แสดงโดยเบราว์เซอร์แรก:
11 ยินดีด้วย
คุณใช้ Firebase SDK สําหรับ Cloud Functions และเพิ่มคอมโพเนนต์ฝั่งเซิร์ฟเวอร์ลงในแอปรับแชท
สิ่งที่เราได้พูดถึง
- การเขียนโค้ด Cloud Functions โดยใช้ Firebase SDK สําหรับ Cloud Functions
- ทริกเกอร์ Cloud Functions ตามเหตุการณ์ของ Auth, Cloud Storage และ Cloud Firestore
- เพิ่มการรองรับ Firebase Cloud Messaging ลงในเว็บแอป
- ทำให้ Cloud Functions ใช้งานได้โดยใช้ Firebase CLI
ขั้นตอนถัดไป
- ดูข้อมูลเกี่ยวกับทริกเกอร์ Cloud Functions ประเภทอื่นๆ
- ใช้ Firebase และ Cloud Functions กับแอปของคุณเอง