يمكنك العثور على مقالات من عام 2017 ... 2018 تركز على استخدام وسائل منخفضة المستوى نسبيًا لإرسال واستقبال رسائل الدفع على الويب ، على سبيل المثال ، باستخدام مكتبة web-push-libs / web-push . لا تزال هذه المكتبة في طور التطور ، ولكن أصبح من السهل الآن العمل مع المكتبات من Firebase.
إنشاء مشروع Firebase
لذلك لنبدأ بإنشاء مشروع على Firebase. مع فتح وحدة التحكم في Firebase ، يجب إنشاء مشروع جديد. في المعلومات العامة-> الإعدادات-> الإعدادات العامة-> تطبيقاتك ، تحتاج إلى إنشاء تطبيق ويب جديد. سيؤدي هذا إلى إنشاء رمز تهيئة تطبيق الويب على جانب الواجهة الأمامية:
<!-- The core Firebase JS SDK is always required and must be listed first -->
<script src="https://www.gstatic.com/firebasejs/7.19.0/firebase-app.js"></script>
<!-- TODO: Add SDKs for Firebase products that you want to use
https://firebase.google.com/docs/web/setup#available-libraries -->
<script src="https://www.gstatic.com/firebasejs/7.19.0/firebase-analytics.js"></script>
<script>
// Your web app's Firebase configuration
var firebaseConfig = {
apiKey: "...",
authDomain: "...",
databaseURL: "...",
projectId: "...",
storageBucket: "...",
messagingSenderId: "...",
appId: "...",
measurementId: "..."
};
// Initialize Firebase
firebase.initializeApp(firebaseConfig);
firebase.analytics();
</script>
في نفس علامة التبويب الخاصة بوحدة التحكم في Firebase ، معلومات عامة- > إعدادات-> Cloud Messaging-> بيانات اعتماد المشروع -> مفتاح الخادم ، نجد المفتاح الخاص ، الذي يمكنك من خلاله إرسال إشعارات عبر خادم firebase.
إرسال رسالة دفع الويب
يمكن لمطوري الواجهة الأمامية إرسال رسائل دفع الويب بأنفسهم باستخدام الأمر curl:
curl -X POST -H "Authorization: key=< >" -H "Content-Type: application/json" -d '{
"data": {
"title": "FCM Message",
"body": "This is an <i>FCM Message</i>",
"icon": "/static/plus.png",
"sound": "/static/push.mp3",
"click_action": "https://google.com",
},
"to": "< >"
}' https://fcm.googleapis.com/fcm/send
يتم وصف الحصول على مفتاح خادم في إعداد مشروع Firebase ، وسيتم وصف الحصول على رمز تسجيل مميز في الحصول على رمز تسجيل مميز .
البيانات مقابل حمولة الإخطار
يمكن إرسال الحمولة في حقل البيانات أو الإعلام لرسالة دفع على الويب. بالنسبة لحمولة الإشعارات ، سيبدو الطلب على النحو التالي (لحمولة البيانات ، انظر الطلب في قسم إرسال رسالة دفع ):
curl -X POST -H "Authorization: key=< >" -H "Content-Type: application/json" -d '{
"notification": {
"title": "FCM Message",
"body": "This is an <i>FCM Message</i>",
"icon": "/static/plus.png",
"click_action": "https://google.com",
},
"to": "< >"
}' https://fcm.googleapis.com/fcm/send
حمولة البيانات والإشعارات لها اختلافان أساسيان:
- تحتوي حمولة الإخطار على مجموعة محددة بدقة من الحقول ، وسيتم تجاهل الحقول الإضافية ، بينما ترسل حمولة البيانات جميع الحقول إلى الواجهة الأمامية دون قيود.
- إذا كان متصفح الويب في الخلفية أو كان الرابط النشط يحتوي على موقع تابع لجهة خارجية ، فإن دفع الويب لحمولة الإشعارات يعرض رسالة دون نقل التحكم إلى معالجات أحداث onMessage ، بينما ينقل دفع حمل البيانات عبر الويب التحكم دائمًا إلى معالجات أحداث onMessage ، ولكن من أجل لعرض رسالة ، يجب عليك إنشاء كائن إعلام بشكل صريح. إذا كان متصفح الويب في حالة نشطة وكان موقعنا مفتوحًا في علامة التبويب النشطة ، فلن يختلف العمل مع البيانات وحمولة الإخطار.
إنشاء كائن الرسائل
للعمل على الواجهة الأمامية مع رسائل دفع الويب ، تحتاج إلى إنشاء كائن مراسلة:
const messaging = window.firebase.messaging();
في هذا الكود ،
firebaseهذا هو كائن عام يتم إنشاؤه أثناء تحميل مكتبات Firebase وتهيئته على جانب الواجهة الأمامية كما هو موضح في إعداد مشروع Firebase . تم تطوير المشروع في Vue.js. لذلك ، فإن توصيل البرامج النصية عبر عنصر نصي بتنسيق html لا يبدو واعدًا. لربط هذه البرامج النصية ، استخدمت المكتبة vue-plugin-load-script:
import Vue from "vue";
import LoadScript from "vue-plugin-load-script";
Vue.use(LoadScript);
var firebaseConfig = {
apiKey: "...",
authDomain: "...",
databaseURL: "...",
projectId: "...",
storageBucket: "...",
messagingSenderId: "...",
appId: "...",
measurementId: "..."
};
Promise.resolve()
.then(() =>
Vue.loadScript(
"https://www.gstatic.com/firebasejs/7.14.0/firebase-app.js"
)
)
.then(() =>
Vue.loadScript(
"https://www.gstatic.com/firebasejs/7.14.0/firebase-messaging.js"
)
)
.then(() =>
Vue.loadScript(
"https://www.gstatic.com/firebasejs/7.14.0/firebase-analytics.js"
)
)
.then(() => {
window.firebase.initializeApp(firebaseConfig);
const messaging = window.firebase.messaging();
... // messaging
});
الحصول على رمز التسجيل
الرمز المميز للتسجيل هو معرف يعرّف بشكل فريد الجهاز ومتصفح الويب ، مما يسمح بإرسال رسالة دفع على الويب إلى جهاز معين ومعالجتها بواسطة متصفح ويب معين:
Notification.requestPermission()
.then(permission => {
if (permission === "granted") {
messaging
.getToken()
.then(token => {
... //
});
} else {
console.log("Unable to get permission to notify.");
}
});
في بعض الظروف ، يمكن تحديث الرمز المميز. وتحتاج إلى التعامل مع حدث تحديث الرمز المميز:
messaging.onTokenRefresh(function() {
messaging
.getToken()
.then(function(refreshedToken) {
... //
});
});
بخصوص هذا الحدث ، لدي سؤال - هل هو مناسب. الحقيقة هي أنه حتى قبل الانتقال إلى FCM ، عمل إجراء تدوير الرمز المميز مع GCM. تم وصف ذلك في مكتبة Android وبشكل غير مباشر في وصف عملية الخادم ، حيث احتوت كل استجابة خادم على رموز متعارف عليها وكان لابد من فحصها وتغييرها باستمرار (ومع ذلك ، كما اتضح فيما بعد ، نادرًا ما يتبعه أي شخص آخر). بعد الانتقال إلى FCM ، لم يعد مفهومًا مثل الرموز الكنسية قيد الاستخدام (على الأرجح لأنه نادرًا ما يتم تعقبها عمليًا). في هذا الصدد ، فإن الحالات التي قد يقع فيها حدث ما ليست واضحة تمامًا
onTokenRefresh().
حدث OnMessage - نسخة مبسطة
سأجيب على الفور لماذا هو مبسط. سنقوم بتبسيطين على الأقل. 1) سنستخدم حمولة الإشعارات لتلقي الرسائل وعرضها إذا كان التطبيق في الخلفية دون عمل إضافي. 2) ننسى أن نظام الأمان على الأجهزة المحمولة لا يسمح بتنفيذ عامل Notification () الجديد.
لذلك ، كما قلنا سابقًا ، بالنسبة لحمولة الإشعارات ، تأتي رسالة دفع الويب ويتم عرضها دون أدنى مشاركة من مطور الواجهة الأمامية (بالطبع ، بعد إرسال رمز التسجيل إلى الخادم). يبقى العمل على حالة متصفح الويب في حالة نشطة والموقع مفتوح في علامة تبويب نشطة:
messaging.onMessage(function(payload) {
const data = { ...payload.notification, ...payload.data };
const notificationTitle = data.title;
const notificationOptions = {
body: data.body,
icon: data.icon,
image: data.image,
click_action: data.click_action,
requireInteraction: true,
data
};
new Notification(payload.notification.title, payload.notification);
});
التعامل مع حدث تلقي رسالة دفع عبر الويب في الخلفية
في هذا القسم ، سنبدأ العمل مع عامل خدمة. وهذا ، من بين أمور أخرى ، يعني أنك بحاجة إلى تكوين الموقع للعمل باستخدام بروتوكول https الآمن. وهذا يعقد على الفور المزيد من التطوير. لذلك ، بالنسبة للحالات البسيطة ، يكفي ما تم وصفه مسبقًا.
للعمل مع مكتبة Firebase ، ملف باسم
firebase-messaging-sw.js. يمكن تعيين اسم ملف آخر ، ولكن على أي حال يجب أن يكون موجودًا في الدليل الجذر نظرًا للطريقة التي تعمل بها حماية متصفح الويب (وإلا فلن يعمل عامل الخدمة هذا للموقع بأكمله).
كقاعدة عامة ، يتم وضع معالج الأحداث أيضًا في هذا الملف
notificationclick. لا يمكنك العثور على أي شيء مختلف عن هذا الرمز:
var firebaseConfig = {
apiKey: "...",
authDomain: "...",
databaseURL: "...",
projectId: "...",
storageBucket: "...",
messagingSenderId: "...",
appId: "...",
measurementId: "..."
};
importScripts("https://www.gstatic.com/firebasejs/7.17.2/firebase-app.js");
importScripts("https://www.gstatic.com/firebasejs/7.17.2/firebase-messaging.js");
firebase.initializeApp(firebaseConfig);
const messaging = firebase.messaging();
messaging.setBackgroundMessageHandler(function(payload) {
const data = { ...payload.notification, ...payload.data };
const notificationTitle = data.title;
const notificationOptions = {
body: data.body,
icon: data.icon,
image: data.image,
requireInteraction: true,
click_action: data.click_action,
data
};
self.registration.showNotification(notificationTitle, notificationOptions);
});
self.addEventListener("notificationclick", function(event) {
const target = event.notification.data.click_action;
event.notification.close();
event.waitUntil(
clients
.matchAll({
type: "window",
includeUncontrolled: true
})
.then(function(clientList) {
for (var i = 0; i < clientList.length; i++) {
var client = clientList[i];
console.log(client.url, client.focus);
if (client.url === target && "focus" in client) {
return client.focus();
}
}
return clients.openWindow(target);
})
);
});
خيار للتعامل مع حدث onMessage مع عامل الخدمة
اسمحوا لي أن أذكرك أنه في القسم الخاص بحدث الرسائل - نسخة مبسطة ، وصفنا بالفعل كيفية التعامل مع رسائل الدفع على الويب. ولكن كان لهذه الطريقة عيبًا مهمًا - فهي لم تعمل على الأجهزة المحمولة نظرًا لخصائص نظام حماية متصفح الويب. للتغلب على هذا العيب ، تم اختراع خيار عامل الخدمة ، حيث تم تضمين كائن الإعلام بالفعل ، ولا يلزم إنشاؤه باستخدام المشغل الجديد:
messaging.onMessage(function(payload) {
play();
navigator.serviceWorker.register("/firebase-messaging-sw.js");
Notification.requestPermission(function(result) {
if (result === "granted") {
navigator.serviceWorker.ready
.then(function(registration) {
const data = { ...payload.notification, ...payload.data };
const notificationTitle = data.title;
const notificationOptions = {
body: data.body,
icon: data.icon,
image: data.image,
click_action: data.click_action,
requireInteraction: true,
data
};
return registration.showNotification(
notificationTitle,
notificationOptions
);
})
.catch(function(error) {
console.log("ServiceWorker registration failed", error);
});
}
});
});
تنبيه عند تلقي رسالة دفع عبر الويب
يجب أن أقول إنه ليس لدينا أي سيطرة عمليًا على كيفية عرض إشعارات الدفع على الأجهزة المختلفة. في بعض الحالات ، ستكون هذه رسالة منبثقة ، وفي حالات أخرى ، تنتقل الدفعة فورًا إلى "لوحة" النظام ، وإذا لم يكن هناك تمثيل صوتي بعد ، فسيتم فقدها للعميل. مع svuk ، كل شيء صعب للغاية. تضمنت المواصفات السابقة مجالًا صوتيًا ، والذي كان مسؤولاً سابقًا عن الصوت عند تلقي رسالة دفع على الويب ، ولكن لا توجد حاليًا مثل هذه الخاصية. في هذا الصدد ، حددت لنفسي هدف إجراء تسجيل صوتي للدفع.
الوصف الذي تتم مواجهته أحيانًا عند إنشاء عنصر صوت بتنسيق html واستدعاء طريقة play () في الواقع لا يعمل بسبب ميزات الأمان لمتصفح الويب (لا يمكن استدعاؤه إلا بنقرة من مستخدم حقيقي). ولكن هناك أيضًا AudioContext () - سنعمل معها:
const play = () => {
try {
const context = new AudioContext();
window
.fetch(soundUrl)
.then(response => response.arrayBuffer())
.then(arrayBuffer => context.decodeAudioData(arrayBuffer))
.then(audioBuffer => {
const source = context.createBufferSource();
source.buffer = audioBuffer;
source.connect(context.destination);
source.start();
});
} catch (ex) {
console.log(ex);
}
};
كل شيء على ما يرام ، ولكن لا يزال لدينا عامل خدمة ليس لديه كائن AudioContext (). لنتذكر أن جميع العاملين يتواصلون من خلال الرسائل. وبعد ذلك سيبدو تلقي الأحداث من عامل الخدمة كما يلي:
try {
const broadcast = new BroadcastChannel("play");
broadcast.onmessage = play;
} catch (ex) {
console.log(ex) ;
}
بالطبع ، لكي يعمل هذا الرمز ، تحتاج إلى 1) المتصفح مفتوح 2) الموقع مفتوح (على الرغم من أنه ليس بالضرورة في علامة التبويب النشطة). لكن لا توجد طريقة أخرى.
بدلا من خاتمة
الآن يمكنك الزفير نوعًا ما وتقول ، هذا كل شيء. لكن ... كل هذا لا يعمل في رحلات السفاري - وهذا موضوع آخر منفصل وسيء التوثيق ، على الرغم من أنه يمكن العثور على العديد من المقالات.
روابط مفيدة
1) habr.com/ru/post/321924
apapacy@gmail.com
24 أغسطس 2020