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

จัดทุกอย่างให้เป็นระเบียบอยู่เสมอด้วยคอลเล็กชัน บันทึกและจัดหมวดหมู่เนื้อหาตามค่ากำหนดของคุณ

1. ภาพรวม

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

3b1284f5144b54f6.png

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

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

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

  • บัตรเครดิต. Cloud Functions สำหรับ 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

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

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

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

เปิดใช้งาน Google Auth

เพื่อให้ผู้ใช้ลงชื่อเข้าใช้แอป เราจะใช้การตรวจสอบสิทธิ์ของ Google ซึ่งจำเป็นต้องเปิดใช้งาน

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

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

8290061806aacb46.png

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

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

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

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

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

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

ในการติดตั้งหรืออัพเกรด 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

เปิดเว็บแอป

บรรทัดสุดท้ายควรแสดง Hosting URL เว็บแอปควรให้บริการจาก URL นี้ ซึ่งควรอยู่ในรูปแบบ https://<project-id>.firebaseapp.com เปิด. คุณควรเห็น UI ที่ใช้งานได้ของแอปแชท

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

3b1284f5144b54f6.png

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

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

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

e926868b0546ed71.png

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

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

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

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

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

cd functions
ls

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

ไฟล์ package.json แสดงรายการการพึ่งพาที่จำเป็นสองรายการแล้ว: 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.

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

7. นำเข้า Cloud Functions และ Firebase Admin modules

จำเป็นต้องใช้สองโมดูลระหว่าง Codelab นี้: firebase-functions firebase เปิดใช้งานการเขียนทริกเกอร์และบันทึกของ Cloud Function ในขณะ 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. ยินดีต้อนรับผู้ใช้ใหม่

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

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

11f5a676fbb1a69a.png

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

fe6d1c020d0744cf.png

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

442c9c10b5e2b245.png

อย่างที่คุณเห็น ข้อความแชทจะถูกเก็บไว้ใน 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 พิเศษเป็นวิธีการของโหนดในการทำให้ฟังก์ชันสามารถเข้าถึงได้จากภายนอกไฟล์ปัจจุบัน และจำเป็นสำหรับ Cloud Functions

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

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

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

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

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

262535d1b1223c65.png

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

1c70e0d64b23525b.png

9. การดูแลรูปภาพ

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

ด้วย Cloud Functions คุณสามารถตรวจจับการอัปโหลดรูปภาพใหม่ได้โดยใช้ทริกเกอร์ 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 Client Library สำหรับ 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 ของคุณ:

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

เมื่อฟังก์ชันถูกเรียกใช้ รูปภาพจะถูกเรียกใช้ผ่าน 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

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

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

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

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

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

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

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

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

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

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

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

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