ส่งการแจ้งเตือนสำหรับเว็บแอปโดยใช้ Cloud Messaging และ Cloud Functions

1. ภาพรวม

ใน Codelab นี้ คุณจะได้เรียนรู้วิธีใช้ฟังก์ชันคลาวด์สำหรับ Firebase เพื่อเพิ่มฟังก์ชันให้กับเว็บแอปแชทโดยการส่งการแจ้งเตือนไปยังผู้ใช้แอปแชท

3b1284f5144b54f6.png

สิ่งที่คุณจะได้เรียนรู้

  • สร้างฟังก์ชัน Google Cloud โดยใช้ Firebase SDK
  • ทริกเกอร์ฟังก์ชันคลาวด์ตามเหตุการณ์ Auth, Cloud Storage และ Cloud Firestore
  • เพิ่มการรองรับ Firebase Cloud Messaging ให้กับเว็บแอปของคุณ

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

  • บัตรเครดิต. ฟังก์ชันคลาวด์สำหรับ Firebase ต้องใช้แผน Firebase Blaze ซึ่งหมายความว่าคุณจะต้องเปิดใช้การเรียกเก็บเงินในโปรเจ็กต์ Firebase โดยใช้บัตรเครดิต
  • โปรแกรมแก้ไข IDE/ข้อความที่คุณเลือก เช่น WebStorm , Atom หรือ Sublime
  • เทอร์มินัลสำหรับรันคำสั่งเชลล์โดยติดตั้ง NodeJS v9
  • เบราว์เซอร์เช่น Chrome
  • รหัสตัวอย่าง ดูขั้นตอนถัดไปสำหรับสิ่งนี้

2. รับโค้ดตัวอย่าง

โคลน ที่เก็บ GitHub จากบรรทัดคำสั่ง:

git clone https://github.com/firebase/friendlychat

นำเข้าแอปเริ่มต้น

ใช้ IDE ของคุณ เปิดหรือนำเข้าไฟล์ android_studio_folder.png ไดเร็กทอรี cloud-functions-start จากไดเร็กทอรีโค้ดตัวอย่าง ไดเรกทอรีนี้มีโค้ดเริ่มต้นสำหรับ Codelab ซึ่งประกอบด้วย Chat Web App ที่ทำงานได้อย่างสมบูรณ์

3. สร้างโปรเจ็กต์ Firebase และตั้งค่าแอปของคุณ

สร้างโครงการ

ใน Firebase Console ให้คลิกที่ Add Project และเรียกมันว่า FriendlyChat

คลิก สร้างโครงการ

อัปเกรดเป็นแผน Blaze

หากต้องการใช้ฟังก์ชันคลาวด์สำหรับ Firebase คุณจะต้องอัปเกรดโปรเจ็กต์ Firebase เป็น แผนการเรียกเก็บเงิน Blaze คุณจะต้องเพิ่มบัตรเครดิตหรือเครื่องมือการเรียกเก็บเงินอื่นลงในบัญชี Google Cloud ของคุณ

โปรเจ็กต์ Firebase ทั้งหมด รวมถึงโปรเจ็กต์ที่อยู่ในแผน Blaze ยังคงมีสิทธิ์เข้าถึงโควต้าการใช้งานฟรีสำหรับฟังก์ชันคลาวด์ ขั้นตอนที่ระบุไว้ใน Codelab นี้จะอยู่ภายในขีดจำกัดการใช้งาน Free Tier อย่างไรก็ตาม คุณจะเห็นค่าบริการเล็กน้อย ( ประมาณ 0.03 USD ) จาก Cloud Storage ซึ่งใช้ในการโฮสต์อิมเมจบิลด์ของ Cloud Functions

หากคุณไม่สามารถเข้าถึงบัตรเครดิตหรือไม่สะดวกในการดำเนินการต่อแผน Blaze ให้พิจารณาใช้ Firebase Emulator Suite ซึ่งจะช่วยให้คุณสามารถจำลองฟังก์ชันคลาวด์ได้ฟรีบนเครื่องในพื้นที่ของคุณ

เปิดใช้งานการรับรองความถูกต้องของ Google

เพื่อให้ผู้ใช้ลงชื่อเข้าใช้แอปได้ เราจะใช้ Google auth ซึ่งจำเป็นต้องเปิดใช้งาน

ใน Firebase Console ให้เปิดส่วน Build > Authentication > Sign-in method (หรือ คลิกที่นี่ เพื่อไปที่นั่น) จากนั้น เปิดใช้งานผู้ให้บริการลงชื่อเข้าใช้ Google แล้วคลิก บันทึก ซึ่งจะทำให้ผู้ใช้สามารถลงชื่อเข้าใช้เว็บแอปด้วยบัญชี Google ของตนได้

นอกจากนี้ โปรดตั้งชื่อที่เปิดเผยต่อสาธารณะของแอปของคุณเป็น Friendly Chat :

8290061806aacb46.png

เปิดใช้งานที่เก็บข้อมูลบนคลาวด์

แอปใช้ Cloud Storage เพื่ออัปโหลดรูปภาพ หากต้องการเปิดใช้งาน Cloud Storage บนโปรเจ็กต์ Firebase ของคุณ โปรดไปที่ส่วนพื้นที่ เก็บข้อมูล แล้วคลิกปุ่ม เริ่มต้น ทำตามขั้นตอนต่างๆ ในนั้น และสำหรับตำแหน่ง Cloud Storage จะมีค่าเริ่มต้นให้ใช้ คลิก เสร็จสิ้น หลังจากนั้น

เพิ่มเว็บแอป

บน Firebase Console ให้เพิ่มเว็บแอป โดยไปที่ การตั้งค่าโครงการ และเลื่อนลงไปที่ เพิ่มแอป เลือกเว็บเป็นแพลตฟอร์มและทำเครื่องหมายในช่องสำหรับตั้งค่าโฮสติ้ง Firebase จากนั้นลงทะเบียนแอปแล้วคลิก ถัดไป สำหรับขั้นตอนที่เหลือ สุดท้ายคลิก ดำเนินการต่อไปยังคอนโซล

4. ติดตั้งอินเทอร์เฟซบรรทัดคำสั่ง Firebase

Firebase Command Line Interface (CLI) จะช่วยให้คุณให้บริการเว็บแอปในเครื่องและปรับใช้เว็บแอปและฟังก์ชันคลาวด์ได้

หากต้องการติดตั้งหรืออัพเกรด CLI ให้รันคำสั่ง npm ต่อไปนี้:

npm -g install firebase-tools

หากต้องการตรวจสอบว่าติดตั้ง CLI อย่างถูกต้อง ให้เปิดคอนโซลแล้วรัน:

firebase --version

ตรวจสอบให้แน่ใจว่าเวอร์ชันของ Firebase CLI นั้นสูงกว่า 4.0.0 เพื่อให้มีคุณสมบัติล่าสุดทั้งหมดที่จำเป็นสำหรับฟังก์ชันคลาวด์ ถ้าไม่เช่นนั้น ให้รัน 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 เปิด. คุณควรเห็น UI การทำงานของแอปแชท

ลงชื่อเข้าใช้แอปโดยใช้ปุ่ม ลงชื่อเข้าใช้ด้วย GOOGLE และเพิ่มข้อความและโพสต์รูปภาพได้ตามต้องการ:

3b1284f5144b54f6.png

หากคุณลงชื่อเข้าใช้แอปเป็นครั้งแรกบนเบราว์เซอร์ใหม่ ตรวจสอบให้แน่ใจว่าคุณอนุญาตการแจ้งเตือนเมื่อได้รับแจ้ง: 8b9d0c66dc36153d.png

เราจะต้องเปิดใช้งานการแจ้งเตือนในภายหลัง

หากคุณคลิก บล็อก โดยไม่ได้ตั้งใจ คุณสามารถเปลี่ยนการตั้งค่านี้ได้โดยคลิกที่ปุ่ม 🔒 ปลอดภัย ทางด้านซ้ายของ URL ในแถบอเนกประสงค์ของ Chrome และสลับแถบที่อยู่ถัดจาก การแจ้งเตือน :

e926868b0546ed71.png

ตอนนี้ เราจะเพิ่มฟังก์ชันการทำงานบางอย่างโดยใช้ Firebase SDK สำหรับฟังก์ชันระบบคลาวด์

6. ไดเร็กทอรีฟังก์ชัน

Cloud Functions ช่วยให้คุณมีโค้ดที่ทำงานบน Cloud ได้อย่างง่ายดายโดยไม่ต้องตั้งค่าเซิร์ฟเวอร์ เราจะอธิบายวิธีสร้างฟังก์ชันที่ตอบสนองต่อเหตุการณ์ฐานข้อมูล Firebase Auth, Cloud Storage และ Firebase Firestore เริ่มจาก Auth กันก่อน

เมื่อใช้ Firebase SDK สำหรับฟังก์ชันระบบคลาวด์ โค้ดฟังก์ชันของคุณจะอยู่ใต้ไดเร็กทอรี functions (ตามค่าเริ่มต้น) โค้ดฟังก์ชันของคุณยังเป็นแอป Node.js ดังนั้นจึงจำเป็นต้องมี package.json ที่ให้ข้อมูลบางอย่างเกี่ยวกับแอปของคุณและแสดงรายการการขึ้นต่อกัน

เพื่อให้ง่ายขึ้นสำหรับคุณ เราได้สร้างไฟล์ functions/index.js ที่จะใส่โค้ดของคุณไว้แล้ว โปรดตรวจสอบไฟล์นี้ก่อนที่จะดำเนินการต่อ

cd functions
ls

หากคุณไม่คุ้นเคยกับ Node.js การเรียนรู้เพิ่มเติมก่อนดำเนินการต่อใน Codelab จะเป็นประโยชน์

ไฟล์ package.json แสดงรายการการขึ้นต่อกันที่จำเป็นสองรายการแล้ว: Firebase SDK สำหรับฟังก์ชันคลาวด์ และ Firebase Admin SDK หากต้องการติดตั้งในเครื่อง ให้ไปที่โฟลเดอร์ functions แล้วรัน:

npm install

ตอนนี้เรามาดูไฟล์ index.js กันดีกว่า:

ดัชนี 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.

เราจะนำเข้าโมดูลที่จำเป็น จากนั้นเขียนฟังก์ชันสามรายการแทนที่สิ่งที่ต้องทำ เริ่มต้นด้วยการนำเข้าโมดูลโหนดที่จำเป็น

7. นำเข้าฟังก์ชันคลาวด์และโมดูลผู้ดูแลระบบ Firebase

จะต้องใช้สองโมดูลในระหว่าง Codelab นี้: firebase-functions เปิดใช้งานการเขียนทริกเกอร์และบันทึกของฟังก์ชันคลาวด์ ในขณะที่ firebase-admin เปิดใช้งานโดยใช้แพลตฟอร์ม Firebase บนเซิร์ฟเวอร์ที่มีสิทธิ์การเข้าถึงของผู้ดูแลระบบเพื่อดำเนินการต่างๆ เช่น การเขียนไปยัง Cloud Firestore หรือการส่งการแจ้งเตือน FCM

ในไฟล์ index.js ให้แทนที่ TODO แรกด้วยข้อมูลต่อไปนี้:

ดัชนี 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. ยินดีต้อนรับผู้ใช้ใหม่

โครงสร้างข้อความแชท

ข้อความที่โพสต์ในฟีดแชท FriendlyChat จะถูกจัดเก็บไว้ใน Cloud Firestore มาดูโครงสร้างข้อมูลที่เราใช้สำหรับข้อความกัน ในการดำเนินการนี้ ให้โพสต์ข้อความใหม่ลงในแชทที่เขียนว่า "Hello World":

11f5a676fbb1a69a.png

สิ่งนี้ควรปรากฏเป็น:

fe6d1c020d0744cf.png

ใน Firebase Console ให้คลิกที่ ฐานข้อมูล Firestore ใต้ส่วน Build คุณควรเห็นคอลเลกชันข้อความและเอกสารหนึ่งฉบับที่มีข้อความที่คุณเขียน:

442c9c10b5e2b245.png

อย่างที่คุณเห็น ข้อความแชทจะถูกจัดเก็บไว้ใน Cloud Firestore เป็นเอกสารที่มี name , profilePicUrl , text และการ timestamp ที่เพิ่มในคอลเลกชัน messages

การเพิ่มข้อความต้อนรับ

Cloud Function แรกจะเพิ่มข้อความต้อนรับ ผู้ใช้ใหม่ เข้าสู่การแชท สำหรับสิ่งนี้ เราสามารถใช้ทริกเกอร์ functions.auth().onCreate ซึ่งจะรันฟังก์ชันทุกครั้งที่ผู้ใช้ลงชื่อเข้าใช้เป็นครั้งแรกในแอป Firebase เพิ่มฟังก์ชัน addWelcomeMessages ลงในไฟล์ index.js ของคุณ:

ดัชนี 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 ในการทำให้ฟังก์ชันเข้าถึงได้ภายนอกไฟล์ปัจจุบัน และจำเป็นสำหรับฟังก์ชันระบบคลาวด์

ในฟังก์ชันข้างต้น เรากำลังเพิ่มข้อความต้อนรับใหม่ที่โพสต์โดย "Firebase Bot" ลงในรายการข้อความแชท เรากำลังดำเนินการนี้โดยใช้วิธี add ในการรวบรวม messages ใน Cloud Firestore ซึ่งเป็นที่เก็บข้อความของการแชท

เนื่องจากนี่เป็นการดำเนินการแบบอะซิงโครนัส เราจึงต้องส่งคืน Promise ที่ระบุว่าเมื่อใดที่ Cloud Firestore เขียนเสร็จแล้ว เพื่อไม่ให้ 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

ทดสอบฟังก์ชัน

เมื่อใช้งานฟังก์ชันสำเร็จแล้ว คุณจะต้องมีผู้ใช้ที่ลงชื่อเข้าใช้เป็นครั้งแรก

  1. เปิดแอปของคุณในเบราว์เซอร์โดยใช้ URL โฮสติ้ง (ในรูปแบบ https://<project-id>.firebaseapp.com )
  2. ด้วยผู้ใช้ใหม่ ให้ลงชื่อเข้าใช้เป็นครั้งแรกในแอปของคุณโดยใช้ปุ่ม ลงชื่อเข้าใช้
  • หากคุณลงชื่อเข้าใช้แอปแล้ว คุณสามารถเปิด Firebase Console Authentication และลบบัญชีของคุณออกจากรายชื่อผู้ใช้ได้ จากนั้นลงชื่อเข้าใช้อีกครั้ง

262535d1b1223c65.png

  1. หลังจากที่คุณลงชื่อเข้าใช้แล้ว ข้อความต้อนรับควรแสดงโดยอัตโนมัติ:

1c70e0d64b23525b.png

9. การกลั่นกรองรูปภาพ

ผู้ใช้สามารถอัปโหลดภาพทุกประเภทในการแชทได้ และสิ่งสำคัญคือต้องกลั่นกรองภาพที่ไม่เหมาะสม โดยเฉพาะอย่างยิ่งในแพลตฟอร์มโซเชียลสาธารณะ ใน FriendlyChat รูปภาพที่เผยแพร่ในการแชทจะถูกจัดเก็บไว้ใน Google Cloud Storage

ด้วยฟังก์ชันคลาวด์ คุณสามารถตรวจจับการอัปโหลดรูปภาพใหม่ได้โดยใช้ทริกเกอร์ functions.storage().onFinalize สิ่งนี้จะทำงานทุกครั้งที่อัปโหลดหรือแก้ไขไฟล์ใหม่ใน Cloud Storage

หากต้องการกลั่นกรองรูปภาพ เราจะดำเนินการตามกระบวนการต่อไปนี้:

  1. ตรวจสอบว่ารูปภาพถูกทำเครื่องหมายว่าสำหรับผู้ใหญ่หรือมีความรุนแรงโดยใช้ Cloud Vision API
  2. หากรูปภาพถูกแฟล็ก ให้ดาวน์โหลดบนอินสแตนซ์ Functions ที่กำลังทำงานอยู่
  3. เบลอภาพโดยใช้ ImageMagick
  4. อัปโหลดภาพเบลอไปยัง Cloud Storage

เปิดใช้ Cloud Vision API

เนื่องจากเราจะใช้ Google Cloud Vision API ในฟังก์ชันนี้ คุณต้องเปิดใช้งาน API บนโปรเจ็กต์ Firebase ของคุณ ไปที่ ลิงก์นี้ จากนั้นเลือกโปรเจ็กต์ Firebase ของคุณและเปิดใช้งาน API:

5c77fee51ec5de49.png

ติดตั้งการพึ่งพา

ในการกลั่นกรองรูปภาพ เราจะใช้ไลบรารีไคลเอ็นต์ 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 ของคุณ

นำเข้าและกำหนดค่าการขึ้นต่อกัน

หากต้องการนำเข้าการขึ้นต่อกันที่ติดตั้งและโมดูลหลักของ Node.js บางส่วน ( path , os และ fs ) ที่เราต้องการในส่วนนี้ ให้เพิ่มบรรทัดต่อไปนี้ที่ด้านบนของไฟล์ index.js ของคุณ:

ดัชนี 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 ของคุณ:

ดัชนี 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'}) เราขอให้อินสแตนซ์ได้รับหน่วยความจำ 2GB แทนที่จะเป็นค่าเริ่มต้น เนื่องจากฟังก์ชันนี้ใช้หน่วยความจำมาก

เมื่อฟังก์ชันถูกทริกเกอร์ รูปภาพจะถูกเรียกใช้ผ่าน Cloud Vision API เพื่อตรวจสอบว่ารูปภาพถูกตั้งค่าสถานะว่าเป็นผู้ใหญ่หรือมีความรุนแรง หากตรวจพบรูปภาพว่าไม่เหมาะสมตามเกณฑ์เหล่านี้ เรากำลังเบลอรูปภาพ ซึ่งดำเนินการในฟังก์ชัน blurImage ดังที่เราจะได้เห็นต่อไป

การเบลอภาพ

เพิ่มฟังก์ชัน blurImage ต่อไปนี้ในไฟล์ index.js ของคุณ:

ดัชนี 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

ทดสอบฟังก์ชัน

เมื่อปรับใช้ฟังก์ชันสำเร็จแล้ว:

  1. เปิดแอปของคุณในเบราว์เซอร์โดยใช้ URL โฮสติ้ง (ในรูปแบบ https://<project-id>.firebaseapp.com )
  2. เมื่อลงชื่อเข้าใช้แอปแล้ว ให้อัปโหลดรูปภาพ: 4db9fdab56703e4a.png
  3. เลือกภาพที่ไม่เหมาะสมที่สุดของคุณที่จะอัปโหลด (หรือคุณสามารถใช้ ภาพซอมบี้กินเนื้อ นี้ได้ !) และหลังจากนั้นสักครู่ คุณจะเห็นการรีเฟรชโพสต์ของคุณด้วยภาพเบลอ: 83dd904fbaf97d2b.png

10. การแจ้งเตือนข้อความใหม่

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

เมื่อใช้ Firebase Cloud Messaging (FCM) คุณจะส่งการแจ้งเตือนไปยังผู้ใช้ข้ามแพลตฟอร์มได้อย่างน่าเชื่อถือ หากต้องการส่งการแจ้งเตือนไปยังผู้ใช้ คุณต้องมีโทเค็นอุปกรณ์ FCM ของผู้ใช้ เว็บแอปแชทที่เราใช้รวบรวมโทเค็นอุปกรณ์จากผู้ใช้แล้วเมื่อพวกเขาเปิดแอปเป็นครั้งแรกบนเบราว์เซอร์หรืออุปกรณ์ใหม่ โทเค็นเหล่านี้จัดเก็บไว้ใน Cloud Firestore ในคอลเลกชัน fcmTokens

หากคุณต้องการเรียนรู้วิธีรับโทเค็นอุปกรณ์ FCM บนเว็บแอป คุณสามารถไปที่ Firebase Web Codelab

ส่งการแจ้งเตือน

หากต้องการตรวจจับเมื่อมีการโพสต์ข้อความใหม่ คุณจะต้องใช้ทริกเกอร์ functions.firestore.document().onCreate Cloud Functions ซึ่งจะเรียกใช้โค้ดของคุณเมื่อมีการสร้างออบเจ็กต์ใหม่ในเส้นทางที่กำหนดของ Cloud Firestore เพิ่มฟังก์ชัน sendNotifications ลงในไฟล์ index.js ของคุณ:

ดัชนี 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 ของคุณ:

ดัชนี 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

ทดสอบฟังก์ชัน

  1. เมื่อปรับใช้ฟังก์ชันสำเร็จแล้ว ให้เปิดแอปของคุณในเบราว์เซอร์โดยใช้ URL โฮสติ้ง (ในรูปแบบ https://<project-id>.firebaseapp.com )
  2. หากคุณลงชื่อเข้าใช้แอปเป็นครั้งแรก ตรวจสอบให้แน่ใจว่าคุณอนุญาตการแจ้งเตือนเมื่อได้รับแจ้ง: 8b9d0c66dc36153d.png
  3. ปิดแท็บแอปแชทหรือแสดงแท็บอื่น: การแจ้งเตือนจะปรากฏเฉพาะในกรณีที่แอปอยู่ในเบื้องหลัง หากคุณต้องการเรียนรู้วิธีรับข้อความในขณะที่แอปของคุณทำงานอยู่เบื้องหน้า โปรดดูที่ เอกสารประกอบของเรา
  4. ใช้เบราว์เซอร์อื่น (หรือหน้าต่างที่ไม่ระบุตัวตน) ลงชื่อเข้าใช้แอปและโพสต์ข้อความ คุณควรเห็นการแจ้งเตือนที่แสดงโดยเบราว์เซอร์แรก: 45282ab12b28b926.png

11. ขอแสดงความยินดี!

คุณได้ใช้ Firebase SDK สำหรับฟังก์ชั่นคลาวด์และเพิ่มส่วนประกอบฝั่งเซิร์ฟเวอร์ให้กับแอปแชท

สิ่งที่เราได้กล่าวถึง

  • การเขียนฟังก์ชันคลาวด์โดยใช้ Firebase SDK สำหรับฟังก์ชันคลาวด์
  • ทริกเกอร์ฟังก์ชันคลาวด์ตามเหตุการณ์ Auth, Cloud Storage และ Cloud Firestore
  • เพิ่มการรองรับ Firebase Cloud Messaging ให้กับเว็บแอปของคุณ
  • ปรับใช้ฟังก์ชันคลาวด์โดยใช้ Firebase CLI

ขั้นตอนถัดไป

เรียนรู้เพิ่มเติม