การแจ้งเตือนแบบพุชของ Firebase ใน React
เผยแพร่แล้ว: 2022-03-10การแจ้งเตือนได้กลายเป็นส่วนที่มั่นคงของเว็บในปัจจุบัน ไม่ใช่เรื่องแปลกที่จะเจอไซต์ที่ขออนุญาตส่งการแจ้งเตือนไปยังเบราว์เซอร์ของคุณ เว็บเบราว์เซอร์ที่ทันสมัยส่วนใหญ่ใช้ push API และสามารถจัดการการแจ้งเตือนแบบพุชได้ การตรวจสอบ caniuse อย่างรวดเร็วแสดงให้เห็นว่า API นั้นได้รับการสนับสนุนอย่างกว้างขวางจากเบราว์เซอร์ที่ใช้โครมสมัยใหม่และเบราว์เซอร์ Firefox
มีบริการต่าง ๆ สำหรับการนำการแจ้งเตือนบนเว็บไปใช้ สิ่งที่โดดเด่นคือ Pusher และ Firebase ในบทความนี้ เราจะใช้การแจ้งเตือนแบบพุชกับบริการ Firebase Cloud Messaging (FCM) ซึ่งเป็น “โซลูชันการส่งข้อความข้ามแพลตฟอร์มที่ให้คุณส่งข้อความได้อย่างน่าเชื่อถือโดยไม่มีค่าใช้จ่าย”
ฉันคิดว่าผู้อ่านมีความคุ้นเคยกับการเขียนแอปพลิเคชันส่วนหลังใน Express.js และ/หรือมีความคุ้นเคยกับ React บ้าง หากคุณพอใจกับเทคโนโลยีเหล่านี้ คุณสามารถทำงานกับส่วนหน้าหรือส่วนหลังได้ เราจะใช้แบ็กเอนด์ก่อน จากนั้นจึงไปยังส่วนหน้า ด้วยวิธีนี้ คุณสามารถใช้ส่วนใดก็ได้ที่ดึงดูดใจคุณมากกว่า
มาเริ่มกันเลยดีกว่า
ประเภทของข้อความ Firebase
เอกสารประกอบ Firebase ระบุว่าการใช้งาน FCM ต้องใช้สององค์ประกอบ
- สภาพแวดล้อมที่เชื่อถือได้ เช่น Cloud Functions for Firebase หรือเซิร์ฟเวอร์แอปสำหรับสร้าง กำหนดเป้าหมาย และส่งข้อความ
- แอพไคลเอนต์ iOS, Android หรือเว็บ (JavaScript) ที่ได้รับข้อความผ่านบริการขนส่งเฉพาะแพลตฟอร์มที่เกี่ยวข้อง
เราจะดูแลรายการที่ 1 ในแอป back-end แบบเร่งด่วน และรายการที่ 2 ในแอป react front-end ของเรา
เอกสารยังระบุด้วยว่า FCM อนุญาตให้เราส่งข้อความสองประเภท
- ข้อความแจ้งเตือน (บางครั้งคิดว่าเป็น “ข้อความที่แสดง”) ได้รับการจัดการโดย FCM SDK โดยอัตโนมัติ
- ข้อความข้อมูลได้รับการจัดการโดยแอปไคลเอ็นต์
เบราว์เซอร์บนเว็บจะจัดการข้อความแจ้งเตือนโดยอัตโนมัติ พวกเขายังสามารถใช้เพย์โหลด data
เสริม ซึ่งต้องจัดการโดยแอพไคลเอนต์ ในบทช่วยสอนนี้ เราจะส่งและรับข้อความข้อมูล ซึ่งแอปไคลเอ็นต์ต้องจัดการ สิ่งนี้ทำให้เรามีอิสระมากขึ้นในการตัดสินใจว่าจะจัดการกับข้อความที่ได้รับอย่างไร
การตั้งค่าโปรเจ็กต์ Firebase
สิ่งแรกที่เราต้องทำคือตั้งค่าโปรเจ็กต์ Firebase FCM เป็นบริการ ดังนั้น เราจึงจำเป็นต้องมีคีย์ API ขั้นตอนนี้กำหนดให้คุณต้องมีบัญชี Google สร้างใหม่หากคุณยังไม่มี คุณสามารถคลิกที่นี่เพื่อเริ่มต้น
หลังจากตั้งค่าบัญชี Google แล้ว ให้ไปที่คอนโซล Firebase
คลิกที่ เพิ่มโครงการ ป้อน ชื่อ โครงการของคุณและคลิกดำเนินการ ต่อ ในหน้าจอถัดไป คุณอาจเลือกที่จะปิดการวิเคราะห์ คุณสามารถเปิดใช้งานได้ในภายหลังจากเมนู Analytics ของหน้าโครงการของคุณ คลิก ดำเนิน การต่อและรอสักครู่เพื่อสร้างโครงการ โดยปกติจะใช้เวลาไม่ถึงนาที จากนั้นคลิกดำเนินการ ต่อ เพื่อเปิดหน้าโครงการของคุณ
เมื่อเราสร้างโปรเจ็กต์สำเร็จแล้ว ขั้นตอนต่อไปคือการรับคีย์ที่จำเป็นเพื่อทำงานกับโปรเจ็กต์ของเรา เมื่อทำงานกับ Firebase เราจำเป็นต้องทำขั้นตอนการกำหนดค่าสำหรับส่วนหน้าและส่วนหลังแยกกัน มาดูกันว่าเราจะได้รับข้อมูลประจำตัวที่จำเป็นในการทำงานกับทั้งคู่ได้อย่างไร
ส่วนหน้า
ในหน้าโครงการ ให้คลิกที่ไอคอนเพื่อเพิ่ม Firebase ลงในเว็บแอปของคุณ
ตั้ง ชื่อเล่น ให้แอปของคุณ ไม่จำเป็นต้องตั้งค่าโฮสติ้ง Firebase คลิกที่ Register app และรอสักครู่เพื่อสิ้นสุดการตั้งค่า ในหน้าจอถัดไป ให้คัดลอกข้อมูลรับรองแอปและจัดเก็บไว้ในที่ใดที่หนึ่ง คุณสามารถเปิดหน้าต่างนี้ทิ้งไว้และกลับมาเปิดใหม่ได้ในภายหลัง
เราต้องการวัตถุการกำหนดค่าในภายหลัง คลิกดำเนินการต่อเพื่อกลับไปยังคอนโซลของคุณ
แบ็กเอนด์
เราต้องการข้อมูลรับรองบัญชีบริการเพื่อเชื่อมต่อกับโปรเจ็กต์ Firebase จากแบ็กเอนด์ ในหน้าโครงการของคุณ ให้คลิกไอคอน รูปเฟือง ถัดจากภาพรวมโครงการเพื่อสร้างบัญชีบริการสำหรับใช้กับแบ็กเอนด์ Express ของเรา อ้างถึงภาพหน้าจอด้านล่าง ทำตามขั้นตอนที่ 1 ถึง 4 เพื่อดาวน์โหลดไฟล์ JSON
พร้อมข้อมูลรับรองบัญชีของคุณ อย่าลืมเก็บไฟล์บัญชีบริการของคุณไว้ในที่ปลอดภัย
ขอแนะนำว่าอย่าดาวน์โหลดจนกว่าคุณจะพร้อมใช้ อย่าลืมกลับมาที่ส่วนเหล่านี้หากต้องการทบทวน
ตอนนี้เราตั้งค่าโปรเจ็กต์ Firebase และเพิ่มเว็บแอปเรียบร้อยแล้ว เรายังได้เห็นวิธีรับข้อมูลประจำตัวที่เราต้องทำงานกับทั้งส่วนหน้าและส่วนหลัง มาดำเนินการส่งการแจ้งเตือนแบบพุชจากแบ็กเอนด์ด่วนของเรากันเถอะ
เริ่มต้น
เพื่อให้การทำงานผ่านบทช่วยสอนนี้ง่ายขึ้น ฉันได้ตั้งค่าโปรเจ็กต์บน Github ที่มีทั้งเซิร์ฟเวอร์และไคลเอนต์ โดยปกติ คุณจะมี repo แยกต่างหากสำหรับแบ็กเอนด์และฟรอนต์เอนด์ตามลำดับ แต่ฉันได้รวบรวมไว้ที่นี่เพื่อให้การทำงานผ่านบทช่วยสอนนี้ง่ายขึ้น
สร้าง fork ของ repo โคลนไปยังคอมพิวเตอร์ของคุณ และเริ่มต้นเซิร์ฟเวอร์ front-end และ back-end ของเรา
- แยก repo และตรวจสอบสาขา
01-get-started
- เปิดโปรเจ็กต์ในตัวแก้ไขโค้ดที่คุณเลือกและสังเกตเนื้อหา
- ในรูทโปรเจ็กต์ เรามีสองโฟลเดอร์คือ
client/
และserver/
นอกจากนี้ยังมีไฟล์ ..editorconfig
,.gitignore
และREADME.md
- โฟลเดอร์ไคลเอนต์มีแอป React นี่คือที่ที่เราจะฟังการแจ้งเตือน
- โฟลเดอร์เซิร์ฟเวอร์มีแอปด่วน นี่คือที่ที่เราจะส่งการแจ้งเตือนจาก แอปนี้มาจากโครงการที่เราสร้างขึ้นในบทความอื่นของฉัน วิธีการตั้งค่าโครงการแบ็กเอนด์ Express API ด้วย PostgreSQL
- เปิดเทอร์มินัลแล้วไปที่
client/
โฟลเดอร์ รันคำสั่งyarn install
เพื่อติดตั้งการพึ่งพาโปรเจ็กต์ จากนั้นรันyarn start
เพื่อเริ่มโครงการ ไปที่https://localhost:3000
เพื่อดูแอพถ่ายทอดสด - สร้างไฟล์
.env
ภายในserver/
โฟลเดอร์และเพิ่มตัวแปรสภาพแวดล้อมCONNECTION_STRING
ตัวแปรนี้เป็น URL การเชื่อมต่อฐานข้อมูลที่ชี้ไปยังฐานข้อมูล PostgreSQL หากคุณต้องการความช่วยเหลือ โปรดดูส่วนการConnecting The PostgreSQL Database And Writing A Model
ในบทความที่เชื่อมโยงของฉัน คุณควรระบุตัวแปรสภาพแวดล้อมPORT
เนื่องจาก React ทำงานบนพอร์ต3000
แล้ว ฉันตั้งค่าPORT=3001
ในไฟล์ ..env
ของฉัน - เปิดเทอร์มินัลแยกต่างหากและไปที่
server/
โฟลเดอร์ รันคำสั่งyarn install
เพื่อติดตั้งการพึ่งพาโปรเจ็กต์ เรียกใช้yarn runQuery
เพื่อสร้างฐานข้อมูลโครงการ เรียกใช้yarn startdev
เพื่อเริ่มโครงการ ไปที่ https://localhost:3001/v1/messages และคุณควรเห็นข้อความบางส่วนในรูปแบบ JSON
ตอนนี้เรามีแอปฟรอนต์เอนด์และแบ็คเอนด์ทำงานแล้ว มาใช้งานการแจ้งเตือนในแบ็กเอนด์กัน
การตั้งค่าการส่งข้อความของผู้ดูแลระบบ Firebase บนแบ็กเอนด์
การส่งการแจ้งเตือนแบบพุชด้วย FCM บนแบ็กเอนด์ต้องใช้ Firebase admin SDK หรือโปรโตคอลเซิร์ฟเวอร์ FCM เราจะใช้ admin SDK ในบทช่วยสอนนี้ นอกจากนี้ยังมีผู้แต่งการแจ้งเตือนซึ่งเหมาะสำหรับ "การทดสอบและส่งข้อความทางการตลาดและการมีส่วนร่วมด้วยการกำหนดเป้าหมายและการวิเคราะห์ที่มีประสิทธิภาพ"
ในเทอร์มินัลของคุณ ไปที่ server/
โฟลเดอร์และติดตั้ง Admin SDK
# install firebase admin SDK yarn add firebase-admin
เปิดไฟล์ .env
ของคุณและเพิ่มตัวแปรสภาพแวดล้อมต่อไปนี้
GOOGLE_APPLICATION_CREDENTIALS="path-to-your-service-account-json-file"
ค่าของตัวแปรนี้คือเส้นทางไปยังข้อมูลประจำตัวของบัญชีบริการที่ดาวน์โหลด ณ จุดนี้ คุณอาจต้องการกลับไปที่ส่วนที่เราสร้างบัญชีบริการสำหรับโครงการของเรา คุณควรคัดลอกรหัสเริ่มต้นของผู้ดูแลระบบจากที่นั่นและดาวน์โหลดไฟล์รหัสบัญชีบริการของคุณด้วย วางไฟล์นี้ใน server/
โฟลเดอร์ของคุณ และเพิ่มลงใน .gitignore
ของคุณ
โปรดจำไว้ว่า ในโครงการจริง คุณควรเก็บไฟล์นี้ไว้ในตำแหน่งที่ปลอดภัยมากบนเซิร์ฟเวอร์ของคุณ อย่าให้ตกไปอยู่ในมือคนผิด
เปิด server/src/settings.js
และส่งออกเส้นทางไฟล์ข้อมูลรับรองของแอปพลิเคชัน
# export the service account key file path export const googleApplicationCredentials = process.env.GOOGLE_APPLICATION_CREDENTIALS;
สร้างไฟล์ server/src/firebaseInit.js
และเพิ่มโค้ดด้านล่าง
import admin from 'firebase-admin'; import { googleApplicationCredentials } from './settings' const serviceAccount = require(googleApplicationCredentials); admin.initializeApp({ credential: admin.credential.cert(serviceAccount), databaseURL: 'your-database-url-here' }); export const messaging = admin.messaging();
เรานำเข้าโมดูลผู้ดูแลระบบจาก firebase-admin
จากนั้นเราจะเริ่มต้นแอปผู้ดูแลระบบด้วยไฟล์บัญชีบริการของเรา สุดท้าย เราสร้างและส่งออกคุณสมบัติการส่งข้อความ
โปรดทราบว่าฉันสามารถส่งผ่านเส้นทางไปยังไฟล์รหัสบัญชีบริการของฉันได้โดยตรง แต่เป็นตัวเลือกที่ปลอดภัยน้อยกว่า ใช้ตัวแปรสภาพแวดล้อมเสมอเมื่อต้องรับมือกับข้อมูลที่ละเอียดอ่อน
ในการตรวจสอบว่าคุณเริ่มต้นได้สำเร็จหรือไม่ ให้เปิดเซิร์ฟเวอร์/src/app.js และรวมบรรทัดต่อไปนี้
import { messaging } from './firebaseInit' console.log(messaging)
เรานำเข้าอินสแตนซ์การส่งข้อความและบันทึกไว้ในคอนโซล คุณควรเห็นบางอย่างเช่นภาพด้านล่าง คุณควรลบสิ่งเหล่านี้เมื่อคุณตรวจสอบว่าผู้ดูแลระบบของคุณได้รับการตั้งค่าอย่างถูกต้อง
หากคุณประสบปัญหาใด ๆ คุณสามารถตรวจสอบสาขา 02-connect-firebase-admin ของ repo ของฉันเพื่อเปรียบเทียบ
เมื่อเราตั้งค่าการส่งข้อความของผู้ดูแลระบบสำเร็จแล้ว ตอนนี้เรามาเขียนโค้ดเพื่อส่งการแจ้งเตือนกัน
การส่งการแจ้งเตือนแบบพุชจากแบ็กเอนด์
การกำหนดค่าข้อความข้อมูล FCM ทำได้ง่ายมาก สิ่งที่คุณต้องทำคือจัดหาเป้าหมายอย่างน้อยหนึ่งรายการและ JSON
ของข้อความที่คุณต้องการส่งไปยังลูกค้า ไม่มีคีย์ที่จำเป็นใน JSON
คุณเป็นผู้ตัดสินใจเองว่าคู่คีย์-ค่าใดที่คุณต้องการรวมไว้ในข้อมูล แบบฟอร์มข้อความข้อมูลใช้งานได้ในทุกแพลตฟอร์ม ดังนั้นการแจ้งเตือนของเราจึงถูกประมวลผลโดยอุปกรณ์มือถือ
มีการกำหนดค่าเพิ่มเติมสำหรับแพลตฟอร์มอื่นๆ ตัวอย่างเช่น มีการตั้งค่า android
ที่ใช้งานได้เฉพาะกับอุปกรณ์ Android และการตั้งค่า apns
ที่ทำงานบนอุปกรณ์ iOS เท่านั้น คุณสามารถดูคู่มือการกำหนดค่าได้ที่นี่
สร้างไฟล์ server/src/notify.js
และป้อนรหัสด้านล่าง
import { messaging } from './firebaseInit'; export const sendNotificationToClient = (tokens, data) => { // Send a message to the devices corresponding to the provided // registration tokens. messaging .sendMulticast({ tokens, data }) .then(response => { // Response is an object of the form { responses: [] } const successes = response.responses.filter(r => r.success === true) .length; const failures = response.responses.filter(r => r.success === false) .length; console.log( 'Notifications sent:', `${successes} successful, ${failures} failed` ); }) .catch(error => { console.log('Error sending message:', error); }); };
เราได้สร้างฟังก์ชันที่ยอมรับอาร์เรย์ของสตริงโทเค็นและออบเจ็กต์ข้อมูล แต่ละสตริงโทเค็นแสดงถึงอุปกรณ์ที่ยอมรับการรับการแจ้งเตือนจากแอปพลิเคชันแบ็คเอนด์ของเรา การแจ้งเตือนจะถูกส่งไปยังไคลเอนต์แต่ละรายในอาร์เรย์โทเค็น เราจะดูวิธีสร้างโทเค็นในส่วนหน้าของบทช่วยสอน
เมธอด sendMulticast
ของอินสแตนซ์การส่งข้อความจะส่งคืนสัญญา เมื่อประสบความสำเร็จ เราได้รับอาร์เรย์ที่เรานับจำนวนความสำเร็จและการแจ้งเตือนที่ล้มเหลว คุณสามารถจัดการกับคำตอบนี้ได้อย่างแน่นอนตามที่คุณต้องการ
ลองใช้ฟังก์ชันนี้เพื่อส่งการแจ้งเตือนทุกครั้งที่มีการเพิ่มข้อความใหม่ลงในฐานข้อมูล
เปิด server/src/controllers/message.js
/src/controllers/message.js และอัปเดตฟังก์ชัน addMessage
import { sendNotificationToClient } from '../notify'; export const addMessage = async (req, res) => { const { name, message } = req.body; const columns = 'name, message'; const values = `'${name}', '${message}'`; try { const data = await messagesModel.insertWithReturn(columns, values); const tokens = []; const notificationData = { title: 'New message', body: message, }; sendNotificationToClient(tokens, notificationData); res.status(200).json({ messages: data.rows }); } catch (err) { res.status(200).json({ messages: err.stack }); } };
ฟังก์ชันนี้จัดการคำขอโพสต์ไปยังปลายทาง /messages
เมื่อสร้างข้อความสำเร็จแล้ว การแจ้งเตือนจะถูกส่งออกไปโดยฟังก์ชัน sendNotificationToClient
ตามด้วยการตอบกลับไปยังไคลเอ็นต์ สิ่งเดียวที่ขาดหายไปในรหัสนี้คือ tokens
ที่จะส่งการแจ้งเตือนไป
เมื่อเราเชื่อมต่อแอปไคลเอ็นต์ เราจะคัดลอกโทเค็นที่สร้างขึ้นและวางลงในไฟล์นี้ ในแอปที่ใช้งานจริง คุณจะต้องจัดเก็บโทเค็นไว้ที่ใดที่หนึ่งในฐานข้อมูลของคุณ
ด้วยโค้ดชิ้นสุดท้ายนี้ เราได้ดำเนินการติดตั้งใช้งานส่วนหลังเสร็จเรียบร้อยแล้ว ตอนนี้ขอสลับไปที่ส่วนหน้า
สาขาที่เกี่ยวข้องใน repo ของฉัน ณ จุดนี้คือ 03-send-notification
การตั้งค่าการแจ้งเตือนการรับส่งข้อความของ Firebase บนไคลเอนต์
มาดูส่วนประกอบหลักของแอป React ส่วนหน้าของเรากัน
เปิด client/src/App.js
และตรวจสอบเนื้อหา ฉันจะละทิ้งคำสั่งนำเข้าส่วนใหญ่และดูที่ตรรกะของโปรแกรม
# library imports import { Messaging } from './Messaging'; axios.defaults.baseURL = 'https://localhost:3001/v1'; const App = () => { return ( <Fragment> <ToastContainer autoClose={2000} position="top-center" /> <Navbar bg="primary" variant="dark"> <Navbar.Brand href="#home">Firebase notifictations with React and Express</Navbar.Brand> </Navbar> <Container className="center-column"> <Row> <Col> <Messaging /> </Col> </Row> </Container> </Fragment> ); }; export default App;
นี่เป็นองค์ประกอบการโต้ตอบปกติที่จัดรูปแบบด้วย react-bootstrap มีส่วนประกอบขนมปังปิ้งอยู่ที่ด้านบนของแอพ ซึ่งเราจะใช้เพื่อแสดงการแจ้งเตือน โปรดทราบว่าเรายังตั้งค่า baseURL
สำหรับไลบรารี axios
ทุกสิ่งในบันทึกย่อเกิดขึ้นภายในองค์ประกอบ <Messaging />
ตอนนี้เรามาดูเนื้อหากัน
เปิด client/src/Messaging.js
และตรวจสอบเนื้อหา
export const Messaging = () => { const [messages, setMessages] = React.useState([]); const [requesting, setRequesting] = React.useState(false); React.useEffect(() => { setRequesting(true); axios.get("/messages").then((resp) => { setMessages(resp.data.messages); setRequesting(false); }); }, []); return ( <Container> {/* form goes here */} <div className="message-list"> <h3>Messages</h3> {requesting ? ( <Spinner animation="border" role="status"> <span className="sr-only">Loading...</span> </Spinner> ) : ( <> {messages.map((m, index) => { const { name, message } = m; return ( <div key={index}> {name}: {message} </div> ); })} </> )} </div> </Container> ); };
เรามีสองตัวแปรสถานะ messages
และการ requesting
messages
แสดงถึงรายการข้อความจากฐานข้อมูลของเรา และการ requesting
เป็นการสลับสถานะตัวโหลดของเรา เรามีบล็อก React.useEffect
ที่เราทำการเรียก API ไปยังจุดปลาย /messages
และตั้งค่าข้อมูลที่ส่งคืนในสถานะ messages
ของเรา
ในคำสั่ง return เราจับคู่ข้อความและแสดง name
และฟิลด์ message
ในหน้าเดียวกัน เราได้รวมแบบฟอร์มสำหรับสร้างข้อความใหม่
<Formik initialValues={{ name: "", message: "", }} onSubmit={(values, actions) => { setTimeout(() => { alert(JSON.stringify(values, null, 2)); actions.setSubmitting(false); toast.success("Submitted succesfully"); }, 1000); }} > {(prop) => { const { handleSubmit, handleChange, isSubmitting } = prop; return ( <> <InputGroup className="mb-3"> <InputGroup.Prepend> <InputGroup.Text>Name</InputGroup.Text> </InputGroup.Prepend> <FormControl placeholder="Enter your name" onChange={handleChange("name")} /> </InputGroup> <InputGroup className="mb-3"> <InputGroup.Prepend> <InputGroup.Text>Message</InputGroup.Text> </InputGroup.Prepend> <FormControl onChange={handleChange("message")} placeholder="Enter a message" /> </InputGroup> {isSubmitting ? ( <Button variant="primary" disabled> <Spinner as="span" size="sm" role="status" animation="grow" aria-hidden="true" /> Loading... </Button> ) : ( <Button variant="primary" onClick={() => handleSubmit()}> Submit </Button> )} </> ); }} </Formik>
เราใช้ไลบรารี Formik
เพื่อจัดการแบบฟอร์มของเรา เราส่งส่วนประกอบ <Formik />
เป็นค่า initialvalues
props, onSubmit
prop และส่วนประกอบแบบฟอร์มที่เราต้องการแสดงผล ในทางกลับกัน เราได้ฟังก์ชันที่มีประโยชน์บางอย่างกลับมา เช่น handleChange
ซึ่งเราสามารถใช้เพื่อจัดการอินพุตแบบฟอร์มของเรา และ handleSubmit
ที่เราใช้ในการส่งแบบฟอร์ม isSubmitting
เป็น boolean
ที่เราใช้เพื่อสลับสถานะปุ่มส่ง
ฉันแนะนำให้คุณลองใช้ formik มันช่วยลดความยุ่งยากในการทำงานกับแบบฟอร์ม เราจะแทนที่รหัสในวิธีการ onSubmit
ในภายหลัง
ตอนนี้เรามาใช้วิธีที่จะขออนุญาตเบราว์เซอร์และกำหนดโทเค็นให้
เพื่อเริ่มใช้ Firebase ในส่วนหน้า เราต้องติดตั้งไลบรารีไคลเอนต์ Firebase JavaScript โปรดทราบว่านี่เป็นแพ็คเกจที่แตกต่างจาก firebase-admin SDK
# install firebase client library yarn add firebase
สร้างไฟล์ client/src/firebaseInit.js
และเพิ่มเนื้อหาต่อไปนี้
import firebase from 'firebase/app'; import 'firebase/messaging'; const config = { apiKey: "API-KEY", authDomain: "AUTH-DOMAIN", databaseURL: "DATABASE-URL", projectId: "PROJECT-ID", storageBucket: "STORAGE-BUCKET", messagingSenderId: "MESSAGING-SENDER-ID", appId: "APP-ID" }; firebase.initializeApp(config); const messaging = firebase.messaging(); // next block of code goes here
เอกสาร Firebase ระบุว่า:
“ไคลเอนต์ Firebase JavaScript เต็มรูปแบบรวมถึงการรองรับการตรวจสอบสิทธิ์ Firebase, ฐานข้อมูลเรียลไทม์ของ Firebase, พื้นที่เก็บข้อมูล Firebase และการรับส่งข้อความบนคลาวด์ของ Firebase”
ดังนั้นที่นี่ เรานำเข้าเฉพาะคุณสมบัติการส่งข้อความ ณ จุดนี้ คุณสามารถอ้างถึงส่วนเกี่ยวกับการสร้างโปรเจ็กต์ Firebase เพื่อรับอ็อบเจ็กต์ config
จากนั้นเราจะเริ่มต้น Firebase และส่งออกคุณสมบัติการส่งข้อความ มาเพิ่มในบล็อกสุดท้ายของโค้ดกัน
export const requestFirebaseNotificationPermission = () => new Promise((resolve, reject) => { messaging .requestPermission() .then(() => messaging.getToken()) .then((firebaseToken) => { resolve(firebaseToken); }) .catch((err) => { reject(err); }); }); export const onMessageListener = () => new Promise((resolve) => { messaging.onMessage((payload) => { resolve(payload); }); });
ฟังก์ชัน requestFirebaseNotificationPermission
ร้องขอการอนุญาตของเบราว์เซอร์ในการส่งการแจ้งเตือนและแก้ไขด้วยโทเค็นหากได้รับการร้องขอ นี่คือโทเค็นที่ FCM ใช้เพื่อส่งการแจ้งเตือนไปยังเบราว์เซอร์ เป็นสิ่งที่ทริกเกอร์ข้อความแจ้งที่คุณเห็นบนเบราว์เซอร์ที่ขออนุญาตเพื่อส่งการแจ้งเตือน
ฟังก์ชัน onMessageListener
จะถูกเรียกใช้เมื่อเบราว์เซอร์อยู่ในเบื้องหน้าเท่านั้น ต่อมา เราจะเขียนฟังก์ชันแยกต่างหากเพื่อจัดการการแจ้งเตือนเมื่อเบราว์เซอร์อยู่ในพื้นหลัง
เปิด client/src/App.js
และนำเข้าฟังก์ชัน requestFirebaseNotificationPermission
import { requestFirebaseNotificationPermission } from './firebaseInit'
จากนั้นในฟังก์ชัน App ให้เพิ่มโค้ดด้านล่างก่อนคำสั่ง return
requestFirebaseNotificationPermission() .then((firebaseToken) => { // eslint-disable-next-line no-console console.log(firebaseToken); }) .catch((err) => { return err; });
เมื่อแอปโหลดฟังก์ชันนี้จะทำงานและขออนุญาตจากเบราว์เซอร์เพื่อแสดงการแจ้งเตือน หากได้รับอนุญาต เราจะบันทึกโทเค็น ในแอปที่ใช้งานจริง คุณควรบันทึกโทเค็นไว้ที่ใดที่แบ็กเอนด์ของคุณสามารถเข้าถึงได้ แต่สำหรับบทช่วยสอนนี้ เราจะคัดลอกและวางโทเค็นลงในแอปส่วนหลัง
เรียกใช้แอพของคุณแล้วคุณจะเห็นข้อความแจ้งคำขอ คลิก อนุญาต และรอให้โทเค็นถูกบันทึกลงในคอนโซล เนื่องจากคุณให้สิทธิ์เบราว์เซอร์ หากเรารีเฟรชหน้า คุณจะไม่เห็นแบนเนอร์อีกต่อไป แต่โทเค็นจะยังถูกบันทึกไว้ในคอนโซล
คุณควรรู้ว่าเบราว์เซอร์ Firefox (v75) ไม่ได้ขออนุญาตการแจ้งเตือนตามค่าเริ่มต้น คำขออนุญาตจะต้องถูกเรียกใช้โดยการกระทำที่ผู้ใช้สร้างขึ้น เช่น การคลิก
นี่เป็นจุดดีสำหรับฉันที่จะยอมรับการเปลี่ยนแปลงของฉัน สาขาที่เกี่ยวข้องคือ 04-request-permission
มากรอกรหัสสำหรับบันทึกข้อความไปยังฐานข้อมูลของเรากัน
เปิด client/src/Messaging.js
และแทนที่ฟังก์ชัน onSubmit
ของแบบฟอร์มของเราด้วยโค้ดด้านล่าง
onSubmit={(values, actions) => { axios .post("/messages", values) .then((resp) => { setMessages(resp.data.messages.concat(messages)); actions.setSubmitting(false); toast.success("Submitted succesfully"); }) .catch((err) => { console.log(err); toast.error("There was an error saving the message"); }); }}
เราส่งคำขอ post
ไปยังปลายทาง /messages
เพื่อสร้างข้อความใหม่ หากคำขอสำเร็จ เราจะนำข้อมูลที่ส่งคืนมาวางไว้ที่ด้านบนสุดของรายการ messages
นอกจากนี้เรายังแสดงขนมปังที่ประสบความสำเร็จ
มาลองดูกันว่าจะได้ผลไหม เริ่มเซิร์ฟเวอร์ส่วนหน้าและส่วนหลัง ก่อนลองส่งคำขอโพสต์ ให้เปิด server/src/controllers/messages.js
และแสดงความคิดเห็นในบรรทัดที่เราส่งการแจ้งเตือน
# this line will throw an error if tokens is an empty array comment it out temporarily // sendNotificationToClient(tokens, notificationData);
ลองเพิ่มข้อความบางข้อความไปยังฐานข้อมูล ผลงาน? ที่ที่ดี ตอนนี้ uncomment บรรทัดนั้นก่อนดำเนินการต่อ
คัดลอกโทเค็นการแจ้งเตือนจากคอนโซลนักพัฒนาซอฟต์แวร์แล้ววางลงในอาร์เรย์โทเค็น โทเค็นเป็นสตริงที่ยาวมาก ดังที่แสดงด้านล่าง
const tokens = [ 'eEa1Yr4Hknqzjxu3P1G3Ox:APA91bF_DF5aSneGdvxXeyL6BIQy8wd1f600oKE100lzqYq2zROn50wuRe9nB-wWryyJeBmiPVutYogKDV2m36PoEbKK9MOpJPyI-UXqMdYiWLEae8MiuXB4mVz9bXD0IwP7bappnLqg', ];
เปิด client/src/Messaging.js
นำเข้า onMessageListener
และเรียกใช้ภายใต้บล็อก useEffect
ตำแหน่งใดๆ ภายในฟังก์ชันนั้นใช้ได้ตราบใดที่อยู่ก่อนคำสั่ง return
import { onMessageListener } from './firebaseInit'; React.useEffect(() => { ... }, []); onMessageListener() .then((payload) => { const { title, body } = payload.data; toast.info(`${title}; ${body}`); }) .catch((err) => { toast.error(JSON.stringify(err)); });
ผู้ฟังส่งคืนคำสัญญาซึ่งแก้ไขเพย์โหลดการแจ้งเตือนเมื่อสำเร็จ จากนั้นเราแสดงชื่อเรื่องและเนื้อหาในขนมปังปิ้ง โปรดทราบว่าเราสามารถดำเนินการอื่นใดเมื่อเราได้รับการแจ้งเตือนนี้ แต่ฉันจะทำให้ทุกอย่างง่ายขึ้นที่นี่ เมื่อเซิร์ฟเวอร์ทั้งสองทำงานอยู่ ให้ลองใช้และดูว่าทำงานได้หรือไม่
ผลงาน? ที่ที่ดี
ในกรณีที่คุณประสบปัญหา คุณสามารถเปรียบเทียบกับ repo ของฉันได้เสมอ สาขาที่เกี่ยวข้อง ณ จุดนี้คือ 05-listen-to-notification
มีเพียงเล็กน้อยที่เราต้องดูแล ตอนนี้เราสามารถเห็นการแจ้งเตือนเมื่อเบราว์เซอร์อยู่ในเบื้องหน้าเท่านั้น ประเด็นเกี่ยวกับการแจ้งเตือนคือควรปรากฏขึ้นไม่ว่าเบราว์เซอร์จะอยู่เบื้องหน้าหรือไม่
หากเราต้องส่งข้อความที่แสดง เช่น เรารวมออบเจ็กต์การ notification
เตือนไว้ในเพย์โหลดการแจ้งเตือนของเรา เบราว์เซอร์จะจัดการเอง แต่เนื่องจากเราส่งข้อความข้อมูล เราจึงต้องบอกเบราว์เซอร์ถึงวิธีปฏิบัติตนตามการแจ้งเตือนเมื่อเบราว์เซอร์ของเราทำงานในเบื้องหลัง
เพื่อจัดการกับการแจ้งเตือนเบื้องหลัง เราจำเป็นต้องลงทะเบียนพนักงานบริการกับลูกค้าส่วนหน้าของเรา
สร้างไฟล์ client/public/firebase-messaging-sw.js
และป้อนเนื้อหาต่อไปนี้:
importScripts('https://www.gstatic.com/firebasejs/7.14.2/firebase-app.js'); importScripts('https://www.gstatic.com/firebasejs/7.14.2/firebase-messaging.js'); const config = { apiKey: "API-KEY", authDomain: "AUTH-DOMAIN", databaseURL: "DATABASE-URL", projectId: "PROJECT-ID", storageBucket: "STORAGE-BUCKET", messagingSenderId: "MESSAGING-SENDER-ID", appId: "APP-ID" }; firebase.initializeApp(config); const messaging = firebase.messaging(); messaging.setBackgroundMessageHandler(function(payload) { console.log('[firebase-messaging-sw.js] Received background message ', payload); const notificationTitle = payload.data.title; const notificationOptions = { body: payload.data.body, icon: '/firebase-logo.png' }; return self.registration.showNotification(notificationTitle, notificationOptions); }); self.addEventListener('notificationclick', event => { console.log(event) return event; });
ที่ด้านบนสุดของไฟล์ เรากำลังนำเข้า firebase-app
firebase-messaging
เนื่องจากเราต้องการเพียงคุณสมบัติการส่งข้อความเท่านั้น ไม่ต้องกังวลหากไวยากรณ์การนำเข้าใหม่ เป็นไวยากรณ์สำหรับการนำเข้าสคริปต์ภายนอกไปยังไฟล์พนักงานบริการ ตรวจสอบให้แน่ใจว่าเวอร์ชันที่กำลังนำเข้านั้นเหมือนกับเวอร์ชันใน package.json
ของคุณ ฉันพบปัญหาที่ฉันแก้ไขโดยการปรับเวอร์ชันให้กลมกลืนกัน
ตามปกติ เราเริ่มต้น Firebase จากนั้นเรียกใช้ setBackgroundMessageHandler
โดยส่งการเรียกกลับซึ่งได้รับข้อความแจ้งเตือนเพย์โหลด ส่วนที่เหลือของรหัสระบุว่าเบราว์เซอร์ควรแสดงการแจ้งเตือนอย่างไร สังเกตว่าเรายังสามารถใส่ไอคอนเพื่อแสดงได้เช่นกัน
นอกจากนี้เรายังสามารถควบคุมสิ่งที่เกิดขึ้นเมื่อเราคลิกที่การแจ้งเตือนด้วยตัวจัดการเหตุการณ์การ notificationclick
ให้ทราบ
สร้างไฟล์ client/src/serviceWorker.js
และป้อนเนื้อหาด้านล่าง
export const registerServiceWorker = () => { if ('serviceWorker' in navigator) { navigator.serviceWorker .register('firebase-messaging-sw.js') .then(function (registration) { // eslint-disable-next-line no-console console.log('[SW]: SCOPE: ', registration.scope); return registration.scope; }) .catch(function (err) { return err; }); } };
ฟังก์ชันนี้ลงทะเบียนไฟล์พนักงานบริการของเรา โปรดทราบว่าเราได้แทนที่เวอร์ชันที่มีรายละเอียดมากขึ้นที่สร้างโดย React ก่อนอื่นเราตรวจสอบว่า serviceWorker
มีอยู่ในวัตถุ navigator
หรือไม่ นี่คือการสนับสนุนเบราว์เซอร์ที่เรียบง่าย หากเบราว์เซอร์รองรับพนักงานบริการ เราจะลงทะเบียนไฟล์พนักงานบริการที่เราสร้างไว้ก่อนหน้านี้
ตอนนี้เปิด client/src/index.js
นำเข้าฟังก์ชันนี้แล้วเรียกใช้
# other imports import { registerServiceWorker } from './serviceWorker' ReactDOM.render( ... ); registerServiceWorker()
หากทุกอย่างเป็นไปด้วยดี คุณควรเห็นขอบเขตของพนักงานบริการที่บันทึกลงในคอนโซลของคุณ
เปิด https://localhost:3000/messaging ในเบราว์เซอร์ที่สอง แล้วสร้างข้อความ คุณควรเห็นการแจ้งเตือนจากเบราว์เซอร์อื่นเข้ามาดู
ด้วยเหตุนี้ เราจึงมาถึงจุดสิ้นสุดของบทช่วยสอนนี้ สาขาที่เกี่ยวข้องใน repo ของฉันคือ 06-handle-background-notification
บทสรุป
ในบทความนี้ เราได้เรียนรู้เกี่ยวกับข้อความแจ้งเตือนประเภทต่างๆ ที่เราสามารถส่งด้วย Firebase Cloud Messaging (FCM) เอพีไอ จากนั้นเราจึงนำประเภท "ข้อความข้อมูล" ไปใช้ในส่วนแบ็คเอนด์ สุดท้าย เราได้สร้างโทเค็นบนแอปไคลเอ็นต์ ซึ่งเราเคยได้รับข้อความแจ้งเตือนที่เรียกใช้โดยแอปแบ็คเอนด์ สุดท้าย เราได้เรียนรู้วิธีการฟังและแสดงข้อความแจ้งเตือนเมื่อเบราว์เซอร์อยู่ในพื้นหลังหรือเบื้องหน้า
ฉันแนะนำให้คุณดูเอกสาร FCM เพื่อเรียนรู้เพิ่มเติม
แหล่งข้อมูลที่เกี่ยวข้อง
- Firebase เว็บไซต์อย่างเป็นทางการ
- Fireact, Orji Chidi Matthew, GitHub
- “Firebase: App Success Made Simple” บล็อก npm
- คอนโซล Firebase
- Firebase Admin Node.js SDK, บล็อก npm
- WebpushConfig, Firebase Docs
-
sendMulticast
, Firebase Docs - ตำราพนักงานบริการ Mozilla
- การแจ้งเตือน Firebase Docs
- Firebase Cloud Messaging, เอกสารประกอบ Firebase
- “วิธีตั้งค่าโครงการแบ็กเอนด์ Express API ด้วย PostgreSQL” Chidi Orji