استفاده از FCM در وب اپلیکیشن ها

در این مقاله میخوام با استفاده از ویو جی اس firebase cloud messaging را با هم تست کنیم.اولین کاری که باید بکنیم اینه که بریم تو firebase console یدونه پروژه درست کنیم. توی گوگل بزنین console.firebase اولین نتیجه معمولا میادمن قبلا ی پروژه ساختم و روند ساخت پروژه هم خیلی سادست واسه همین وارد نمیشم اما بعد از ساخت پروژه باید ی اپ به پروژه اضافه کنیم با کلیک روی گزینه Add appهمینطور که میبینید من قبلا یکی ساختم به اسم testfcmبه محض اینکه اپ رو بسازید بهتون credential ها رو میده که مهمترین چیزی که تو این تصویر هست firebaseConfig که در ادامه نیازمون میشه. میتونید همینجا کپیش کنید.حالا به اگه باز به firebase console برگردین اپتون ساخته شده!اینجا با کلیک کردن روی اپ ی منو باز میشه:روی icon تنظیمات کلیک کنید. وارد این قسمت که بشید ابتدا روی تب general هستین. حالا اگه اسکرول کنید پایین باز هم همون credential هارو که کپی کردین میتونید ازینجا هم کپی کنید.خب تا اینجا ی پروژه ساختیم ی اپ وب هم توی پروژه ساختیم.قبل از اینکه شروع کنیم لازم میدونم ی نکته رو بگم: حتما ریپازیتوری کامل این مقاله رو به ادرس: https://github.com/alizangiabadicode/simple-push-fcm-vue-js کلون کنید. چرا؟ چون که من خیلی نمیگم فلان متود رو دقیقا کجا بذارید و شما میتونید دقیقا از توی این ریپو ببینید من چیو کجا گذاشتمحالا میتونیم وارد اپ vue js بشیم و پکیج فایربیس رو نصب کنیم با دستور:npm i firebase --saveبعد ازین ی فایل با پسوند js داخل روت پروژه میسازیم. اسمش رو هرچی دوست دارید بذاریدکد زیر رو داخلش کپی پیست کنیدقسمتایی که نوشتم YOUR_CREDENTIAL رو با همین credential هایی که گفتم کپی کنید جایگزین کنید.import firebase from "firebase";export const initializeFirebase = () => {firebase.initializeApp({apiKey: "YOUR_CRENTIAL",authDomain: "YOUR_CRENTIAL",databaseURL: "YOUR_CRENTIAL",projectId: "YOUR_CRENTIAL",storageBucket: "YOUR_CRENTIAL",messagingSenderId: "YOUR_CRENTIAL",appId: "YOUR_CRENTIAL",measurementId: "YOUR_CRENTIAL",});const messaging = firebase.messaging();}-خب حالا بریم سراغ این کد!خب اولش اومدم فایربیس رو ایمپورتش کردم بعد ی فانکشن رو ریختم داخل ی متغیر(دلیلشو یخورده جلوتر میگم)اما چیزایی که داخل این فانکشن هستن یکی اول اومدم متود intitilaizeApp رو صدا زدم و بعد هم مسیجینگ رو ازش ی instance گرفتم. خب حالا وقت اینه که بریم از فایربیس ی توکن بگیریم.خب مهمترین چیزی که الان نیاز هست داشتن ی توکن هست که ازین طریق بتونیم نوتیفیکیشن دریافت کنیم!واسه گرفتن توکن یازه که چند تا متود دیگه هم اضافه کنیم.اولین متود RequestPermission هست:function RequestPermission(messaging) {messaging.requestPermission().then(function(permission) {if (permission === "granted") {console.log("have Permission");// calls method again and to sent token to servergetStartToken();} else {console.log("Permission Denied");}}).catch((err) => {console.log(err);});}این متود چیکار میکنه؟ اول اینکه ی instance از messaging رو به عنوان ورودی میگیره بعد میاد با متود requestPermission در خواست نوتیفیکیشن میکنه. که نتیجه این در خواست ی promise هست و اگه granted باشه یعنی کاربر قبول کرده نوتیفیکیشن بفرستیم اگه نباشه خب کاربر قبول نکرده!حالا شاید سوال پیش بیاد این قبول کردن یا نکردن کاربر چجوریه که حالا در ادامه خودتون بصورت بصری میبینید!اگع یکم دیگه دقت کنید داخل ایف اول ی متود رو داره صدا میزنه به اسم getStartToken که حالا وقتشه بیایم این متود رو اضافه کنیمmessaging.getToken().then((currentToken) => {console.log({currentToken,});if (currentToken) {// sendTokenToServer(currentToken)} else {RequestPermission(messaging);}}).catch(() => {console.log("error ocurred");});}خب این متود چجوریه؟ اول از همه داره ی instance از مسیجینگ رو به عنوان ورودی میگیره. بعد اومده متود get token رو صدا زده که از اسمش معلومه داره درخواست توکن جدید میکنه. که خروجی این متوده هم promise هست. داخل قسمت then میاد چک میکنه که توکنی گرفتهاول حالتی که نگرفته رو بررسی کنیم یعنی else: اینجا میاد همون متود RequestPermission رو صدا میزنه تا پرمیشن بگیرهاگه داخل if بیاد هم ی متود داره به اسم sendTokenToServer که کامنت شده در حال حاضر. اینجا اگه لازم باشه شما میاد توکن رو سمت ای پی ای میفرستید که ذخیره بشه.خب ما تا الان دو تا متود نوشتیم که اگه دقت کرده باشید هر دو تا همدیگرو داخل خودشون به طریقی صدا زدن اما ما کدوم یکی رو باید داخل متود initializeFirebase صدا بزنیم؟اگر یوزر اجازه داده باشه که براش نوتیفیکیشن بفرستیم دیگه لازم نیست که اصلا اجازه بگیریم اگر نه باید درخواست کنیم.پس اول متود getStartToken رو صدا میزنیمحالا واسه تست همین چیزایی که نوشتیم میام داخل فایل main.js متود initializeFirebase رو که اکسپورت کردم رو ایمپورت میکنم و صدا میزنم.حالا میام اپ رو ران میکنیم.اولین چیزی که باهاش روبرو میشین درخواست نوتیفیکیشن هست:روی allow کلیک کنید. بعد کنسول رو باز کنید. باید توکن رو بتونید ببینید: اوکی تا اینجا ما تونستیم ی توکن از فایربیس بگیریم. اما حالا قراره با این توکن چیکار کنیم؟ازین توکن استفاده میشه تا بتونیم خودمون دستی برای اپمون نوتیفیکیشن بفرستیم.اما قبل از اون ی نکته در مورد نوتیفیکیشن ها یا در اینجا بهتره بگیرم web push بدونیم.ما دو نوع نوتیفیکیشن میگیرم. زمانی که اپ باز هست و زمانی که اپ باز نیست یا حداقل اون تب توی مرورگر باز نیست.برای هدنل کردن نوع اول باید از متود استفاده کنیم. اما چجوری؟!messaging.(function(payload) {console.log("on Message", payload);});اینجا اومدم متود رو روی messaging صدا زدم و ی متود بهش پاس دادم. درواقع بهش ی کال بک پاس دادم که میاد صرفا لاگ میکنه.خب حالا شاید فکر کنید که این باید کار کنه اما اینجوری نیست!قبل از تست لازمه که سرویس ورکر فایربیس رو اضافه کنیم. اگر از ویو استفاده میکنید داخل پوشه پابلیک و اگر از فریمورک دیگه ای استفاده میکنید با فایل firebase-messaging-sw.js رو جایی قرار بدید که از طریق domain/firebase-messaging-sw.js در دسترس باشهداخل این فایل میایم کد زیر رو اضافه میکنیمimportScripts("https://www.gstatic.com/firebasejs/7.20.0/firebase-app.js");importScripts("https://www.gstatic.com/firebasejs/7.20.0/firebase-messaging.js");const firebaseConfig = {apiKey: "YOUR_CRENTIAL",authDomain: "YOUR_CRENTIAL",databaseURL: "YOUR_CRENTIAL",projectId: "YOUR_CRENTIAL",storageBucket: "YOUR_CRENTIAL",messagingSenderId: "YOUR_CRENTIAL",appId: "YOUR_CRENTIAL",measurementId: "YOUR_CRENTIAL",};firebase.initializeApp(firebaseConfig);const messaging = firebase.messaging();خب اینجا چیکار کردیم؟ ابتدا دو تا اسکریپت رو اوردیم. یکی بیس فایربیس و دومی قسمت مسیجینگبعد اومدیم initialize کردیم خود فایربیس رو. بعدشم اومدیم ی instance از messaging ساختیم.اینجا ی نکته رو لازم میدونم بگم. اینکه میگم ی instance ساختم فقط ی ساخته شدن نیست. یک کار های دیگه ای هم پشت صحنه هندل میشن. مثلا در ادامه که میخوایم نوتیف بفرستیم میبینیم که اگه اپ رو فوکوس نکنیم و داخل payload ی سری اطلاعات رو داخل کلید notification بفرستیم خود فایربیس نوتیفیکیشن ما رو به ی صورت استانداردی میاد نشون میده. حالا ادامه اینارو خواهیم دید.خب کجا بودیم؟! میخواستیم توی حالتی که تب برنامه باز هست و نوتیفیکیشن میرسه تستش کنیم. بعد اومدیم سرویس ورکر فایربیس رو اضافه کردیم. حالا زمان تست هست.خب حالا چجوری نوتیف بفرستیم؟ دوتاشون که خودم رفتم رو میگمیکی اینکه از طریق console فایربیس انجامش بدیم. ی راه دیگه هم از طریق پست من.من از پست من استفاده میکنم علتشم اینه که در کنسول فایربیس ی سری محدودیت داریم.curl -X POST -H &quotAuthorization: key=YOUR-SERVER-KEY&quot -H &quotContent-Type: application/json&quot -d '{ &quotnotification&quot: { &quottitle&quot: &quotPortugal vs. Denmark&quot, &quotbody&quot: &quot5 to 1&quot, &quoticon&quot: &quotfirebase-logo.png&quot, &quotclick_action&quot: &quothttp://localhost:8080&quot }, &quotto&quot: &quotYOUR_FIREBASE_TOKEN&quot }' &quothttps://fcm.googleapis.com/fcm/sendخب شما کد بالا رو کپی کنید و وارد پست من بشین. اون بالا سمت چپ ی دکمه ایمپورت میبینید روش کلیک کنید. ی دیالوگ باز میشه. وارد قسمت raw text بشید:و پیست کنید. حالا روی continue بزنید(لازمه ی خورده اسکرول کنید پایین تا دکمش دیده شه)خب میبینید ک ی ریکوئست ساخته شده.وارد قسمت بادی بشید. ی کلید میبینید به اسم "to". کاری که میکنید این هست که وارد تبی که وب اپلیکیشن باز هست میشین و همون توکنی که لاگ کردید رو کپی و به عنوان مقدار "to" قرار میدید.حالا وارد قسمت headers بشید.مقدار authorization رو نگاه کنید. key=YOUR_SERVER_KEY. شما باید برید داخل console فایربیس و وارد اپی که ساختید بشین و تب cloud messaging رو باز کنید و server key رو کپی کنید و اینجا جایگزین کنید.خب حالا میتونید روی دکمه send توی پست من بزنید. حواستون باشه که توی مرورگر روی تب برنامتون باشید.خب کنسول رو هم باز کنید. باید ی همچین چیزی ببینید.همونجور که میبنید که ابجکت هست که شامل کلید نوتیفیکیشنه. درواقع همون payload ای که فرستادین رو دارین اینجا میبینید.خب حالا تب مرورگرخودتون رو عوض کنید. باز روی دکمه send پست من کلیک کنید.ناگهان ی نوتیفیکیشن به این شکل میبینید.سوال پیش میاد چرا؟ چون که شما الان توی تب دیگه ای هستید و متود اجرا نمیشه و اگه یادتون باشه گفتم هر وقت توی payload بیایین با کلید notification دیتا بفرستین خود فایربیس میاد هندل میکنه.خب موردی که پیش میاد این هست که شاید دلمون نخواست خود فایربیس هندل کنه اونموقع باید چیکار کنیم؟!خب اولین چیزی که خودتون باید حدس بزنید اینه که توی پیلود دیگه نباید چیزی با کلید notification بفرستید. درسته! اما خب اگه اینکارو کنید دیگه نوتیفیکیشن نشون داده نمیشه. سوال اینه چجوری نوتیفیکیشن نشون بدیم در سرویس ورکر؟با متود onBackgroundMessage! کد زیر رو کپی کنید تا بریم سراغ اصل مطلب!messaging.onBackgroundMessage(function(payload) {console.log("Received background message ",payload);// Customize notification hereconst notificationTitle = "Background Message Title"const notificationOptions = {body: payload.data.body,image: payload.data.image,};console.log({notificationTitle,notificationOptions})return self.registration.showNotification(notificationTitle,notificationOptions);});زمانی بدون پیلود notification بفرستیم این متود صدا زده میشه و تنها نکته ای که کد بالا داره اینه که شما دارید داده ها رو از ی فیلد به اسم دیتا میفرستید. یعنی اگر تا الان داخل قسمت body پست من ی همچین چیزی ارسال میکردین: { "notification": { "title": "Portugal vs. Denmark", "body": "5 to 1", "icon": "firebase-logo.png", "click_action": "http://localhost:8080" }, "to": "YOUR_FIREBASE_TOKEN" }از الان فقط جای notification بذارید data. یعنی:{ "data": { "title": "Portugal vs. Denmark", "body": "5 to 1", "icon": "firebase-logo.png", "click_action": "http://localhost:8080" }, "to": "YOUR_FIREBASE_TOKEN" }خب الان اگه تست کنید همون نتیجه قبلی رو میگیرید.بعضی وقت ها میخوایم اگه نوتیفیکیشن کلیک شد بفهمیم و هندلش کنیم با استفاده از کد زیر ممکن میشهself.addEventListener('notificationclick', function(event) {console.log('notification clicked', event)})اگر جایی اشتباه کرده بودم ممنون میشم کامنت کنید.اگر هم سوالی داشتید میتوانید در توییتر یا در کامنت ها از من بپرسید.