เกี่ยวกับ Codelab นี้
1 ภาพรวม
ในโค้ดแล็บนี้ คุณจะได้เรียนรู้วิธีใช้ Cloud Functions for Firebase เพื่อเพิ่มฟังก์ชันการทำงานให้กับเว็บแอปแชทโดยการส่งการแจ้งเตือนไปยังผู้ใช้แอปแชท
สิ่งที่คุณจะได้เรียนรู้
- สร้างฟังก์ชันของ Google Cloud โดยใช้ 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 โดยใช้บัญชี Google
- คลิกปุ่มเพื่อสร้างโปรเจ็กต์ใหม่ แล้วป้อนชื่อโปรเจ็กต์ (เช่น
FriendlyChat
)
- คลิกต่อไป
- หากได้รับแจ้ง ให้อ่านและยอมรับข้อกำหนดของ Firebase แล้วคลิกต่อไป
- (ไม่บังคับ) เปิดใช้ความช่วยเหลือจาก AI ในคอนโซล Firebase (เรียกว่า "Gemini ใน Firebase")
- สำหรับ Codelab นี้ คุณไม่จำเป็นต้องใช้ Google Analytics ดังนั้นให้ปิดตัวเลือก Google Analytics
- คลิกสร้างโปรเจ็กต์ รอให้ระบบจัดสรรโปรเจ็กต์ แล้วคลิกดำเนินการต่อ
อัปเกรดเป็นแพ็กเกจ Blaze
หากต้องการใช้ Cloud Functions for Firebase และ Cloud Storage for Firebase โปรเจ็กต์ Firebase ของคุณต้องอยู่ในแพ็กเกจราคาแบบจ่ายเมื่อใช้ (Blaze) ซึ่งหมายความว่าโปรเจ็กต์ต้องลิงก์กับบัญชีการเรียกเก็บเงินในระบบคลาวด์
- บัญชีสำหรับการเรียกเก็บเงินของ Cloud ต้องมีวิธีการชำระเงิน เช่น บัตรเครดิต
- หากเพิ่งเริ่มใช้ Firebase และ Google Cloud โปรดตรวจสอบว่าคุณมีสิทธิ์รับเครดิต$300 และบัญชีสำหรับการเรียกเก็บเงินในระบบคลาวด์แบบทดลองใช้ฟรีหรือไม่
- หากคุณกำลังทำ Codelab นี้เป็นส่วนหนึ่งของกิจกรรม โปรดสอบถามผู้จัดว่ามีเครดิต Cloud ให้หรือไม่
หากคุณไม่มีสิทธิ์เข้าถึงบัตรเครดิตหรือไม่สะดวกที่จะใช้แพ็กเกจราคา Blaze ต่อไป ให้ลองใช้ Firebase Emulator Suite ซึ่งจะช่วยให้คุณจำลอง Cloud Functions ได้ฟรีในเครื่องของคุณ
โปรเจ็กต์ Firebase ทั้งหมด รวมถึงโปรเจ็กต์ที่ใช้แพ็กเกจราคา Blaze จะยังคงมีสิทธิ์เข้าถึงโควต้าการใช้งาน Cloud Functions แบบไม่มีค่าใช้จ่าย ขั้นตอนที่ระบุไว้ในโค้ดแล็บนี้จะอยู่ภายในขีดจำกัดการใช้งานของรุ่นฟรี อย่างไรก็ตาม คุณจะเห็นค่าใช้จ่ายเล็กน้อย (ประมาณ $0.03) จาก Cloud Storage ซึ่งใช้เพื่อโฮสต์อิมเมจบิลด์ของ Cloud Functions
หากต้องการอัปเกรดโปรเจ็กต์เป็นแพ็กเกจ Blaze ให้ทำตามขั้นตอนต่อไปนี้
- ในคอนโซล Firebase ให้เลือกอัปเกรดแพ็กเกจ
- เลือกแพ็กเกจ Blaze ทำตามวิธีการบนหน้าจอเพื่อลิงก์บัญชีสำหรับการเรียกเก็บเงินใน Cloud กับโปรเจ็กต์
หากคุณต้องสร้างบัญชีสำหรับการเรียกเก็บเงินใน Cloud เป็นส่วนหนึ่งของการอัปเกรดนี้ คุณอาจต้องกลับไปที่ขั้นตอนการอัปเกรดใน Firebase Console เพื่อทำการอัปเกรดให้เสร็จสมบูรณ์
เปิดใช้ Google Auth
หากต้องการให้ผู้ใช้ลงชื่อเข้าใช้แอป เราจะใช้การตรวจสอบสิทธิ์ของ Google ซึ่งต้องเปิดใช้
ในคอนโซล Firebase ให้เปิดส่วนสร้าง > การตรวจสอบสิทธิ์ > แท็บวิธีการลงชื่อเข้าใช้ (หรือคลิกที่นี่เพื่อไปที่แท็บดังกล่าว) จากนั้นเปิดใช้ผู้ให้บริการลงชื่อเข้าใช้ 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 ในแถบออมนิบาร์ของ Chrome แล้วสลับแถบข้างการแจ้งเตือน
ตอนนี้เราจะเพิ่มฟังก์ชันการทำงานบางอย่างโดยใช้ Firebase SDK สำหรับ Cloud Functions
6 ไดเรกทอรีฟังก์ชัน
Cloud Functions ช่วยให้คุณมีโค้ดที่ทำงานในระบบคลาวด์ได้อย่างง่ายดายโดยไม่ต้องตั้งค่าเซิร์ฟเวอร์ เราจะอธิบายวิธีสร้างฟังก์ชันที่ตอบสนองต่อเหตุการณ์ในฐานข้อมูล Firebase Auth, Cloud Storage และ Firebase Firestore มาเริ่มกันที่ Auth
เมื่อใช้ Firebase SDK สำหรับ Cloud Functions โค้ดฟังก์ชันจะอยู่ในไดเรกทอรี functions
(โดยค่าเริ่มต้น) โค้ดฟังก์ชันยังเป็นแอป Node.js ด้วย จึงต้องมี package.json
ที่ให้ข้อมูลบางอย่างเกี่ยวกับแอปและแสดงรายการการอ้างอิง
เราได้สร้างไฟล์ functions/index.js
ไว้แล้วเพื่อให้คุณใช้งานได้ง่ายขึ้น ซึ่งเป็นที่ที่คุณจะวางโค้ดของคุณ โปรดตรวจสอบไฟล์นี้ก่อนดำเนินการต่อ
cd functions
ls
หากคุณไม่คุ้นเคยกับ Node.js การศึกษาข้อมูลเพิ่มเติมเกี่ยวกับ Node.js ก่อนที่จะทำ Codelab ต่อไปจะเป็นประโยชน์
ไฟล์ 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 โมดูลจะต้องใช้ในระหว่าง Codelab นี้ โดย 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
- หากมีการแจ้งว่ารูปภาพไม่เหมาะสม ให้ดาวน์โหลดรูปภาพในอินสแตนซ์ของฟังก์ชันที่กำลังทำงาน
- เบลอรูปภาพโดยใช้ 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
ซึ่งจะเป็นการติดตั้งแพ็กเกจในเครื่องและเพิ่มแพ็กเกจเป็นทรัพยากร Dependency ที่ประกาศไว้ในไฟล์ 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 และอัปโหลดเวอร์ชันที่เบลออีกครั้งใน Storage Bucket จากนั้นเราจะลบไฟล์ในอินสแตนซ์ 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
) - เมื่อลงชื่อเข้าใช้แอปแล้ว ให้ทำดังนี้เพื่ออัปโหลดรูปภาพ
- เลือกรูปภาพที่ดูน่ากลัวที่สุดเพื่ออัปโหลด (หรือจะใช้ซอมบี้กินเนื้อนี้ก็ได้) หลังจากนั้นไม่นาน คุณจะเห็นโพสต์รีเฟรชพร้อมรูปภาพเวอร์ชันเบลอ
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 กับแอปของคุณเอง