الإشعارات الفورية على الويب المفتوح

إذا سألت مجموعة من المطورين عن ميزات الجهاز المحمول التي تفتقد إليها في الويب، تكون الإشعارات الفورية دائمًا عالية في القائمة

تتيح الإشعارات الفورية للمستخدمين الموافقة على تلقّي التحديثات في الوقت المناسب من المواقع الإلكترونية التي يستخدمونها. تسمح لك بإعادة جذبهم بشكل فعّال من خلال محتوى مخصص وتفاعلي.

اعتبارًا من الإصدار 42 من Chrome، أصبحت Push API تتوفّر Notification API لما يلي: المطورين.

تعتمد واجهة برمجة تطبيقات Push في Chrome على بعض التقنيات المختلفة، بما في ذلك بيانات تطبيق الويب ومشغّلو الخدمات في هذه المشاركة، سنلقي نظرة على كل واحدة من هذه التقنيات، ولكن الحد الأدنى لتشغيل الرسائل الفورية. للحصول على فهم أفضل لبعض والميزات الأخرى للبيانات والإمكانات بلا اتصال بالإنترنت للعاملين في الخدمة، يُرجى الاطّلاع على الروابط أعلاه

سننظر أيضًا في ما ستتم إضافته إلى واجهة برمجة التطبيقات في الإصدارات المستقبلية من Chrome، وأخيرًا سيكون لدينا الأسئلة الشائعة

استخدام خدمة المراسلة الفورية في Chrome

يصف هذا القسم كل خطوة تحتاج إلى إكمالها لدعم الدفع المراسلة في تطبيق الويب.

تسجيل مشغّل الخدمات

هناك تبعية وجود عامل خدمة لتنفيذ رسائل الدفع على الويب. وسبب ذلك هو أنه عند تلقي رسالة فورية، تشغيل مشغّل الخدمات الذي يعمل في الخلفية دون مفتوحة، وإرسال حدث حتى تتمكن من تحديد كيفية التعامل مع ذلك إرسال رسالة فورية.

في ما يلي مثال على كيفية تسجيل عامل خدمة في تطبيق الويب. فعندما اكتملت عملية التسجيل بنجاح، نسميها initialiseState()، والتي سنتناوله قريبًا.

var isPushEnabled = false;



window.addEventListener('load', function() {
    var pushButton = document.querySelector('.js-push-button');
    pushButton.addEventListener('click', function() {
    if (isPushEnabled) {
        unsubscribe();
    } else {
        subscribe();
    }
    });

    // Check that service workers are supported, if so, progressively
    // enhance and add push messaging support, otherwise continue without it.
    if ('serviceWorker' in navigator) {
    navigator.serviceWorker.register('/service-worker.js')
    .then(initialiseState);
    } else {
    console.warn('Service workers aren\'t supported in this browser.');
    }
});

يعمل معالج النقر على الأزرار على اشتراك المستخدم أو إلغاء اشتراكه لإرسال الرسائل. isPushEnabled هو متغير عمومي يتتبّع ببساطة ما إذا كان خيار إرسال البيانات المراسلة مشترك حاليًا أم لا. ستتم الإشارة إليها طوال مقتطفات الرمز.

بعد ذلك، نتحقّق من توفّر مشغّلي الخدمة قبل تسجيل service-worker.js. ملفه المنطقي للتعامل مع رسالة الدفع. هنا نحن يخبرون المتصفّح بأنّ ملف JavaScript هذا هو مشغّل الخدمات على موقعنا الإلكتروني

إعداد الحالة الأولية

مثال على تجربة مستخدم خدمة المراسلة الفورية المفعَّلة وغير المفعَّلة في Chrome

بعد تسجيل مشغّل الخدمات، علينا ضبط حالة واجهة المستخدِم.

سيتوقّع المستخدمون واجهة مستخدم بسيطة لتفعيل الرسائل الفورية أو إيقافها على موقعك الإلكتروني. ويتوقعون التحديث باستمرار لأي تغييرات تحدث. بعبارة أخرى، هذه الكلمات، إذا كانت تسمح برسائل الدفع لموقعك، فاترك بعد أسبوع، من المفترض أن تُبرز واجهة المستخدم أنه تم تفعيل رسائل الدفع بالفعل.

يمكنك العثور على بعض إرشادات تجربة المستخدم في هذا المستند، سنركز في هذه المقالة على الجوانب الفنية.

في هذه المرحلة، قد تعتقد أنّ هناك حالتَين فقط يجب التعامل معهم، مُفعَّلة أو موقوفة. ومع ذلك، هناك بعض الدول الأخرى المحيطة والإشعارات التي يجب أخذها في الاعتبار

مخطّط بياني يسلّط الضوء على الاعتبارات المختلفة لحالة الدفع في Chrome

هناك عدد من واجهات برمجة التطبيقات التي نحتاج إلى التحقق منها قبل تمكين الزر، وإذا كان كل شيء متوافقًا، يمكننا تفعيل واجهة المستخدم وضبط الحالة الأولية على للإشارة إلى ما إذا كانت رسائل الدفع المباشر مشتركًا أم لا.

وبما أنّ معظم عمليات التحقّق هذه تؤدي إلى إيقاف واجهة المستخدم، عليك وضبط الحالة الأولية على "إيقاف". وهذا أيضًا يتجنب أي لبس في حالة يمثل مشكلة في JavaScript في صفحتك، على سبيل المثال، لا يمكن أن يكون ملف JS تم تنزيله أو أوقف المستخدم JavaScript.

<button class="js-push-button" disabled>
    Enable Push Messages
</button>

بهذه الحالة الأولية، يمكننا إجراء عمليات التحقق الموضحة أعلاه في initialiseState()، أي بعد تسجيل مشغّل الخدمات.

// Once the service worker is registered set the initial state
function initialiseState() {
    // Are Notifications supported in the service worker?
    if (!('showNotification' in ServiceWorkerRegistration.prototype)) {
    console.warn('Notifications aren\'t supported.');
    return;
    }

    // Check the current Notification permission.
    // If its denied, it's a permanent block until the
    // user changes the permission
    if (Notification.permission === 'denied') {
    console.warn('The user has blocked notifications.');
    return;
    }

    // Check if push messaging is supported
    if (!('PushManager' in window)) {
    console.warn('Push messaging isn\'t supported.');
    return;
    }

    // We need the service worker registration to check for a subscription
    navigator.serviceWorker.ready.then(function(serviceWorkerRegistration) {
    // Do we already have a push message subscription?
    serviceWorkerRegistration.pushManager.getSubscription()
        .then(function(subscription) {
        // Enable any UI which subscribes / unsubscribes from
        // push messages.
        var pushButton = document.querySelector('.js-push-button');
        pushButton.disabled = false;

        if (!subscription) {
            // We aren't subscribed to push, so set UI
            // to allow the user to enable push
            return;
        }

        // Keep your server in sync with the latest subscriptionId
        sendSubscriptionToServer(subscription);

        // Set your UI to show they have subscribed for
        // push messages
        pushButton.textContent = 'Disable Push Messages';
        isPushEnabled = true;
        })
        .catch(function(err) {
        console.warn('Error during getSubscription()', err);
        });
    });
}

نظرة عامة مختصرة على هذه الخطوات:

  • نتحقق من توفّر "showNotification" في ServiceWorkerRecord. والنموذج الأوّلي. بدونه، لن نتمكّن من عرض إشعار من مشغّل الخدمات. عند تلقي رسالة فورية.
  • نحن نتحقّق من قيمة Notification.permission الحالية للتأكّد من أنّها ليست "denied" يعني رفض الإذن أنّه لا يمكنك عرض الإشعارات. إلى أن يغيّر المستخدم الإذن يدويًا في المتصفّح.
  • للتحقق مما إذا كانت الرسائل الفورية متاحة، نتحقق من أنّ PushManager متاح المتاحة في كائن النافذة.
  • وأخيرًا، استخدمنا pushManager.getSubscription() للتحقق مما إذا كنا لديهم اشتراك أم لا. وفي هذه الحالة، سنرسل تفاصيل الاشتراك إلى للتأكد من أن لدينا المعلومات الصحيحة وتعيين واجهة المستخدم للإشارة إلى تكون رسائل الدفع هذه مُفعَّلة أم لا. سنلقي نظرة على تفاصيل في عنصر الاشتراك لاحقًا ضمن هذه المقالة

ننتظر حتى يتم حلّ مشكلة navigator.serviceWorker.ready للتحقّق من ولتفعيل زر الضغط لأنه لا يتم الاشتراك إلا بعد انتهاء الخدمة يمكنك في الواقع الاشتراك في رسائل الدفع.

الخطوة التالية هي التعامل عندما يريد المستخدم تمكين رسائل الدفع، ولكن قبل أن نتمكن من إجراء ذلك، نحتاج إلى إعداد مشروع على Google Play Console وإضافة بعض المعلمات إلى البيان الخاص بنا تستخدم المراسلة عبر السحابة الإلكترونية من Firebase (FCM) التي كانت تُعرف سابقًا باسم خدمة مراسلة عبر السحابة الإلكترونية من Google (GCM).

إنشاء مشروع على Firebase Developer Console

استخدام Chrome خدمة "المراسلة عبر السحابة الإلكترونية من Firebase" للتعامل مع إرسال رسائل الدفع وتسليمها لكن، من أجل تستخدم واجهة برمجة تطبيقات FCM، فستحتاج إلى إعداد مشروع على Firebase Developer Console.

الخطوات التالية تخص Chrome وOpera لأجهزة Android وSamsung المتصفّح الذي يستخدمونه من خلال "المراسلة عبر السحابة الإلكترونية من Firebase". وسنناقش طريقة عمل ذلك في المتصفحات الأخرى لاحقًا في المقالة.

إنشاء مشروع مطوّر جديد على Firebase

للبدء، يجب إنشاء مشروع جديد على https://console.firebase.google.com/ بالنقر على "إنشاء مشروع جديد"

لقطة شاشة جديدة لمشروع Firebase

أضِف اسم مشروع وأنشئ المشروع وسيتم نقلك إلى المشروع. لوحة المعلومات:

الصفحة الرئيسية لمشروع Firebase

من لوحة التحكم هذه، انقر على الترس بجوار اسم مشروعك في الأعلى في الجانب الأيسر وانقر فوق "إعدادات المشروع".

قائمة إعدادات مشروع Firebase

في صفحة الإعدادات، انقر على "خدمة المراسلة عبر السحابة الإلكترونية" .

قائمة &quot;المراسلة عبر السحابة الإلكترونية من Firebase&quot; لمشروع Firebase

تحتوي هذه الصفحة على مفتاح واجهة برمجة التطبيقات لرسائل الدفع، والذي سنستخدمه لاحقًا، ومعرف المرسل الذي نحتاج إلى وضعه في بيان تطبيق الويب في الخطوة التالية .

إضافة بيان تطبيق ويب

لإرسال المحتوى، يجب إضافة ملف بيان يتضمّن الحقل gcm_sender_id، من أجل تحقيق النجاح في اشتراك Push. هذه المعلمة مطلوبة فقط من خلال Chrome وOpera لنظام التشغيل Android ومتصفح Samsung حتى يتمكنوا من استخدام FCM / GCM.

تستخدم هذه المتصفّحات مَعلمة gcm_sender_id عند اشتراك المستخدمين عبر خدمة "المراسلة عبر السحابة الإلكترونية من Firebase". وهذا يعني أن خدمة "المراسلة عبر السحابة الإلكترونية من Firebase" يمكنها التعرّف على جهاز المستخدم من تطابُق معرّف المُرسِل مع مفتاح واجهة برمجة التطبيقات المقابل وأن المستخدم خادمك بإرسال رسائل الدفع إليها.

في ما يلي ملف بيان بسيط للغاية:

{
    "name": "Push Demo",
    "short_name": "Push Demo",
    "icons": [{
        "src": "images/icon-192x192.png",
        "sizes": "192x192",
        "type": "image/png"
        }],
    "start_url": "/index.html?homescreen=1",
    "display": "standalone",
    "gcm_sender_id": "<Your Sender ID Here>"
}

عليك ضبط القيمة gcm_sender_id لمعرّف المُرسِل من مشروع Firebase لديك.

بعد حفظ ملف البيان في مشروعك (يكون ملف Manifest.json مفيدًا )، فارجع إليه من HTML باستخدام العلامة التالية في رأس ملف .

<link rel="manifest" href="/manifest.json">

إذا لم تتم إضافة بيان ويب بهذه المَعلمات، ستحصل على استثناء. عند محاولة اشتراك المستخدم في إرسال الرسائل، مع ظهور رسالة الخطأ "Registration failed - no sender id provided" أو "Registration failed - permission denied"

الاشتراك في خدمة Push Messaging

الآن بعد إعداد ملف البيان، يمكنك الرجوع إلى JavaScript في مواقعك الإلكترونية.

للاشتراك، يجب استدعاء الطريقة Unsubscribe() في PushManager، التي يمكنك الوصول إليها من خلال ServiceWorkerRegistration:

سيطلب هذا الإجراء من المستخدم منح المصدر الإذن لإرسال رسالة فورية. الإشعارات. بدون هذا الإذن، لن تتمكن من تنفيذ الاشتراك.

في حال إرجاع الوعد بحلول طريقة subscription()، سيتم منحك PushSubscription الذي سيحتوي على نقطة نهاية.

يجب حفظ نقطة النهاية على خادمك لكل موقع المستخدم، لأنّك ستحتاج إليه لإرسال رسائل فورية في وقت لاحق.

يشترك الرمز التالي في اشتراك المستخدم في خدمة رسائل الدفع:

function subscribe() {
    // Disable the button so it can't be changed while
    // we process the permission request
    var pushButton = document.querySelector('.js-push-button');
    pushButton.disabled = true;

    navigator.serviceWorker.ready.then(function(serviceWorkerRegistration) {
    serviceWorkerRegistration.pushManager.subscribe()
        .then(function(subscription) {
        // The subscription was successful
        isPushEnabled = true;
        pushButton.textContent = 'Disable Push Messages';
        pushButton.disabled = false;

        // TODO: Send the subscription.endpoint to your server
        // and save it to send a push message at a later date
        return sendSubscriptionToServer(subscription);
        })
        .catch(function(e) {
        if (Notification.permission === 'denied') {
            // The user denied the notification permission which
            // means we failed to subscribe and the user will need
            // to manually change the notification permission to
            // subscribe to push messages
            console.warn('Permission for Notifications was denied');
            pushButton.disabled = true;
        } else {
            // A problem occurred with the subscription; common reasons
            // include network errors, and lacking gcm_sender_id and/or
            // gcm_user_visible_only in the manifest.
            console.error('Unable to subscribe to push.', e);
            pushButton.disabled = false;
            pushButton.textContent = 'Enable Push Messages';
        }
        });
    });
}

في هذه المرحلة، يكون تطبيق الويب جاهزًا لاستلام الرسائل الفورية، إلا أنّه ليس هناك. حتى نضيف أداة معالجة حدث الإرسال إلى ملف عامل الخدمة.

أداة معالجة حدث الدفع لمشغّل الخدمات

عند تلقي رسالة فورية (سنتحدث عن كيفية إرسال رسالة فورية بشكل فعلي في القسم التالي)، حدث فوري إلى مشغّل الخدمات لديك، وستحتاج عندها إلى لعرض إشعار.

self.addEventListener('push', function(event) {
    console.log('Received a push message', event);

    var title = 'Yay a message.';
    var body = 'We have received a push message.';
    var icon = '/images/icon-192x192.png';
    var tag = 'simple-push-demo-notification-tag';

    event.waitUntil(
    self.registration.showNotification(title, {
        body: body,
        icon: icon,
        tag: tag
    })
    );
});

يسجِّل هذا الرمز أداة معالجة حدث الدفع التلقائي ويعرض إشعارًا مع عنوان محدد مسبقًا ونص أساسي ورمز وعلامة إشعار. إنّ إحدى التفاصيل الدقيقة التي يجب إبرازها في هذا المثال هي "event.waitUntil()". . تأخذ هذه الطريقة الوعد ويوسِّع نطاق فترة معالج الأحداث (أو يمكن اعتبارها الحفاظ على الخدمة عامل واحد على قيد الحياة)، حتى يصبح الوعد مستقرة، في هذه الحالة، يكون الوعد الذي تم تمريره إلى event.waitUntil هو الوعد الذي تم إرجاعه من showNotification().

تعمل علامة الإشعار ومعرِّف الإشعارات الفريدة. إذا أرسلنا رسالتين فوريتين إلى نفس نقطة نهاية، مع مهلة قصيرة بينها وعرض الإشعارات بالعلامة نفسها، سيعرض المتصفح الإشعار الأول ويستبدله الإشعار الثاني عند تلقي الرسالة الفورية.

إذا أردت عرض إشعارات متعددة في وقت واحد، يمكنك استخدام علامة مختلفة ولا توجد علامة على الإطلاق. سنطّلع على مثال أكثر اكتمالاً لعرض إشعار لاحقًا في هذا مشاركة. في الوقت الحالي، لنجعل الأمور بسيطة ونرى ما إذا كان إرسال رسالة فورية سيؤدي إلى ظهور هذا الإشعار.

إرسال رسالة فورية

لقد اشتركنا في الرسائل الفورية وعامل الخدمات جاهز لعرض لذا، فقد حان الوقت لإرسال رسالة فورية من خلال ميزة "المراسلة عبر السحابة الإلكترونية من Firebase".

ينطبق هذا فقط على المتصفحات التي تستخدم ميزة "المراسلة عبر السحابة الإلكترونية من Firebase".

عند إرسال المتغير PushSubscription.endpoint إلى خادمك، نقطة نهاية "المراسلة عبر السحابة الإلكترونية من Firebase" خاصة. ولها معلَمة في نهاية عنوان URL هي registration_id.

قد تكون نقطة النهاية كمثال:

https://fcm.googleapis.com/fcm/send/APA91bHPffi8zclbIBDcToXN_LEpT6iA87pgR-J-MuuVVycM0SmptG-rXdCPKTM5pvKiHk2Ts-ukL1KV8exGOnurOAKdbvH9jcvg8h2gSi-zZJyToiiydjAJW6Fa9mE3_7vsNIgzF28KGspVmLUpMgYLBd1rxaVh-L4NDzD7HyTkhFOfwWiyVdKh__rEt15W9n2o6cZ8nxrP

عنوان URL الخاص بخدمة "المراسلة عبر السحابة الإلكترونية من Firebase" هو:

https://fcm.googleapis.com/fcm/send

سيكون registration_id:

APA91bHPffi8zclbIBDcToXN_LEpT6iA87pgR-J-MuuVVycM0SmptG-rXdCPKTM5pvKiHk2Ts-ukL1KV8exGOnurOAKdbvH9jcvg8h2gSi-zZJyToiiydjAJW6Fa9mE3_7vsNIgzF28KGspVmLUpMgYLBd1rxaVh-L4NDzD7HyTkhFOfwWiyVdKh__rEt15W9n2o6cZ8nxrP

وينطبق ذلك على المتصفّحات التي تستخدم "المراسلة عبر السحابة الإلكترونية من Firebase". في المتصفح العادي، قد تحتاج مجرد الحصول على نقطة نهاية وسوف تستدعي نقطة النهاية هذه بطريقة قياسية فقد يعمل بغض النظر عن عنوان URL.

ويعني هذا أنّه عليك التحقّق ممّا إذا كانت نقطة النهاية في خادمك مخصصة للمراسلة عبر السحابة الإلكترونية من Firebase، وإذا كان الأمر كذلك، يمكنك استخراج مبلغ التسجيل_id. للقيام بذلك في بايثون، يمكنك القيام بشيء مثل:

if endpoint.startswith('https://fcm.googleapis.com/fcm/send'):
    endpointParts = endpoint.split('/')
    registrationId = endpointParts[len(endpointParts) - 1]

    endpoint = 'https://fcm.googleapis.com/fcm/send'

بعد الحصول على رقم تعريف التسجيل، يمكنك إجراء مكالمة مع واجهة برمجة تطبيقات FCM API. إِنْتَ يمكنك العثور على المستندات المرجعية حول واجهة برمجة تطبيقات FCM API هنا.

في ما يلي الاعتبارات الأساسية التي يجب مراعاتها عند الاتصال بخدمة "المراسلة عبر السحابة الإلكترونية من Firebase":

  • عنوان منح الإذن بقيمة key=&lt;YOUR_API_KEY&gt; عند استدعاء واجهة برمجة التطبيقات، حيث يشير &lt;YOUR_API_KEY&gt; إلى مفتاح واجهة برمجة التطبيقات من مشروع Firebase
    • تستخدم خدمة "المراسلة عبر السحابة الإلكترونية من Firebase" مفتاح واجهة برمجة التطبيقات للعثور على معرّف المُرسِل المناسب، الذي أعطاه المستخدم إذنًا لمشروعك، وأخيرًا ضمان إدراج عنوان IP للخادم في القائمة المسموح بها لهذا المشروع.
  • عنوان Content-Type مناسب لـ application/json أو application/x-www-form-urlencoded;charset=UTF-8 اعتمادًا على ما إذا كنت إرسال البيانات بتنسيق JSON أو بيانات النموذج.
  • مصفوفة من registration_ids: تمثّل معرّف التسجيل الذي واستخراجها من نقاط النهاية من المستخدمين.

يُرجى الاطّلاع على المستندات حول كيفية إرسال رسائل فورية من الخادم، ولكن للاطّلاع سريعًا على مشغّل الخدمات، يمكنك استخدام cURL لإرسال رسالة فورية إلى متصفحك

التبديل بين "&lt;YOUR_API_KEY&gt;" و"&lt;YOUR_REGISTRATION_ID&gt;" في أمر cURL هذا باستخدام الأمر الخاص بك ويمكنك تشغيله من الوحدة الطرفية.

من المفترض أن ترى إشعارًا مميزًا:

    curl --header "Authorization: key=<YOUR_API_KEY>" --header
    "Content-Type: application/json" https://fcm.googleapis.com/fcm/send -d
    "{\"registration_ids\":[\"<YOUR_REGISTRA>TION_ID\"]}"
مثال على رسالة فورية من Chrome لنظام Android

عند تطوير منطق الخلفية، تذكر أن عنوان التفويض يكون تنسيق نص POST خاصًا بنقطة نهاية FCM، لذا يجب اكتشاف متى نقطة النهاية للمراسلة عبر السحابة الإلكترونية من Firebase وإضافة العنوان بشكل مشروط وتنسيق نص POST. بالنسبة إلى المتصفحات الأخرى (ونأمل أن يكون Chrome في المستقبل) ستحتاج إلى تنفيذ بروتوكول Web Push.

ومن الآثار السلبية للتطبيق الحالي لواجهة برمجة تطبيقات Push API في Chrome أنك لا يمكنهم إرسال أي بيانات مع رسالة فورية. كلا، لا شيء. السبب في ذلك هو أنّه في عملية تنفيذ مستقبلية، سيتعين تشفير بيانات الحمولة على قبل إرسالها إلى نقطة نهاية رسائل الدفع. بهذه الطريقة تكون نقطة النهاية، لن يتمكن أي من مزودي خدمة الدفع هذا من عرض محتوى إرسال رسالة فورية. يوفر هذا أيضًا الحماية من الثغرات الأمنية الأخرى مثل الثغرات الأمنية التحقق من صحة شهادات HTTPS وهجمات الوسيط بين ومزود خدمة الإرسال. هذا التشفير غير متاح بعد، لذا ستحتاج إلى تنفيذ عملية جلب للحصول على المعلومات المطلوبة ملء إشعار.

مثال على حدث فوري أكثر اكتمالاً

الإشعار الذي رأيناه حتى الآن بسيط للغاية، وبقدر ما تذهب العينات، وسيكون سيئ جدًا في تغطية حالة الاستخدام في العالم الحقيقي.

من الناحية الواقعية، سيرغب معظم المستخدمين في الحصول على بعض المعلومات من خادمهم قبل عرض الإشعار. قد تكون هذه بيانات لملء وعنوان الإشعار والرسالة بشيء محدد، أو الانتقال إلى مستوى أبعد من ذلك والتخزين المؤقت لبعض الصفحات أو البيانات، حتى عندما ينقر المستخدم على الإشعار، يصبح كل شيء متاحًا على الفور عند فتح المتصفح - حتى إذا الشبكة غير متاحة في ذلك الوقت.

في الرمز التالي، نجلب بعض البيانات من واجهة برمجة التطبيقات، ونحول الرد إلى واستخدامه لتعبئة الإشعار.

self.addEventListener('push', function(event) {
    // Since there is no payload data with the first version
    // of push messages, we'll grab some data from
    // an API and use it to populate a notification
    event.waitUntil(
    fetch(SOME_API_ENDPOINT).then(function(response) {
        if (response.status !== 200) {
        // Either show a message to the user explaining the error
        // or enter a generic message and handle the
        // onnotificationclick event to direct the user to a web page
        console.log('Looks like there was a problem. Status Code: ' + response.status);
        throw new Error();
        }

        // Examine the text in the response
        return response.json().then(function(data) {
        if (data.error || !data.notification) {
            console.error('The API returned an error.', data.error);
            throw new Error();
        }

        var title = data.notification.title;
        var message = data.notification.message;
        var icon = data.notification.icon;
        var notificationTag = data.notification.tag;

        return self.registration.showNotification(title, {
            body: message,
            icon: icon,
            tag: notificationTag
        });
        });
    }).catch(function(err) {
        console.error('Unable to retrieve data', err);

        var title = 'An error occurred';
        var message = 'We were unable to get the information for this push message';
        var icon = URL_TO_DEFAULT_ICON;
        var notificationTag = 'notification-error';
        return self.registration.showNotification(title, {
            body: message,
            icon: icon,
            tag: notificationTag
        });
    })
    );
});

الجدير بالذكر مرة أخرى، الإشارة إلى أن event.waitUntil() تتخذ وعودًا ما يعني أنّ الوعد الذي تم إرجاعه من قِبل showNotification() يعني ألّا يخرج أداة معالجة الحدث إلى أن تكتمل استدعاء fetch() غير المتزامن، سيظهر لك الإشعار.

ستلاحظ أننا نعرض إشعارًا حتى في حال حدوث خطأ. هذا هو لأننا إذا لم نقم بذلك، فسيعرض Chrome إشعاره العام.

فتح عنوان URL عندما ينقر المستخدم على إشعار

عندما ينقر المستخدم على إشعار، يتم إرسال حدث notificationclick. في مشغّل الخدمات لديك. داخل المعالج، يمكنك اتخاذ الإجراء المناسب، مثل التركيز على علامة تبويب أو فتح نافذة ذات عنوان URL محدد:

self.addEventListener('notificationclick', function(event) {
    console.log('On notification click: ', event.notification.tag);
    // Android doesn't close the notification when you click on it
    // See: http://crbug.com/463146
    event.notification.close();

    // This looks to see if the current is already open and
    // focuses if it is
    event.waitUntil(
    clients.matchAll({
        type: "window"
    })
    .then(function(clientList) {
        for (var i = 0; i < clientList.length; i++) {
        var client = clientList[i];
        if (client.url == '/' && 'focus' in client)
            return client.focus();
        }
        if (clients.openWindow) {
        return clients.openWindow('/');
        }
    })
    );
});

يفتح هذا المثال المتصفِّح على جذر الموقع الإلكتروني، من خلال التركيز على الحالية، إن وجدت، وتفتح علامة جديدة أخرى.

تتوفّر مشاركة مخصّصة لبعض الإجراءات التي يمكنك تنفيذها باستخدام واجهة برمجة التطبيقات Notification API هنا.

إلغاء الاشتراك في جهاز مستخدم

إذا اشتركت في جهاز أحد المستخدمين يتلقّى رسائل فورية، ولكن كيف يمكنك ذلك؟ إلغاء اشتراكهم؟

إن الأشياء الرئيسية المطلوبة لإلغاء الاشتراك في جهاز المستخدم هي الاتصال طريقة "unsubscribe()" على PushSubscription وإزالة نقطة النهاية من خوادمك (حتى لا إرسال رسائل فورية تعرف أنه لن يتم استلامها). تقوم التعليمة البرمجية أدناه هذا بالضبط:

function unsubscribe() {
    var pushButton = document.querySelector('.js-push-button');
    pushButton.disabled = true;

    navigator.serviceWorker.ready.then(function(serviceWorkerRegistration) {
    // To unsubscribe from push messaging, you need get the
    // subscription object, which you can call unsubscribe() on.
    serviceWorkerRegistration.pushManager.getSubscription().then(
        function(pushSubscription) {
        // Check we have a subscription to unsubscribe
        if (!pushSubscription) {
            // No subscription object, so set the state
            // to allow the user to subscribe to push
            isPushEnabled = false;
            pushButton.disabled = false;
            pushButton.textContent = 'Enable Push Messages';
            return;
        }

        var subscriptionId = pushSubscription.subscriptionId;
        // TODO: Make a request to your server to remove
        // the subscriptionId from your data store so you
        // don't attempt to send them push messages anymore

        // We have a subscription, so call unsubscribe on it
        pushSubscription.unsubscribe().then(function(successful) {
            pushButton.disabled = false;
            pushButton.textContent = 'Enable Push Messages';
            isPushEnabled = false;
        }).catch(function(e) {
            // We failed to unsubscribe, this can lead to
            // an unusual state, so may be best to remove
            // the users data from your data store and
            // inform the user that you have done so

            console.log('Unsubscription error: ', e);
            pushButton.disabled = false;
            pushButton.textContent = 'Enable Push Messages';
        });
        }).catch(function(e) {
        console.error('Error thrown while unsubscribing from push messaging.', e);
        });
    });
}

إبقاء الاشتراك محدّثًا

قد لا تتم مزامنة الاشتراكات بين خدمة "المراسلة عبر السحابة الإلكترونية من Firebase" وخادمك. يُرجى التأكد من أنّ: يحلل الخادم نص الاستجابة لعبارة POST الخاصة بالإرسال من واجهة برمجة تطبيقات FCM، بحثًا عن نتائج error:NotRegistered وcanonical_id، كما هو موضّح في مستندات "المراسلة عبر السحابة الإلكترونية من Firebase".

وقد لا تتم مزامنة الاشتراكات أيضًا بين مشغّل الخدمة الخادم. فعلى سبيل المثال، بعد إتمام الاشتراك/إلغاء الاشتراك بنجاح، قد تظهر اتصال الشبكة من تحديث الخادم، أو قد يحتاج المستخدم إبطال إذن الإشعارات، ما يؤدي إلى إلغاء اشتراك تلقائي الاسم المعرِّف مثل هذه الحالات عن طريق التحقق من نتيجة serviceWorkerRegistration.pushManager.getSubscription() بشكل دوري (على سبيل المثال عند تحميل الصفحة) ومزامنتها مع الخادم. قد ترغب أيضًا في إعادة الاشتراك تلقائيًا إذا لم يعد لديك اشتراك Notification.permission == 'granted'.

في "sendSubscriptionToServer()"، عليك التفكير في كيفية تعاملك مع التطبيق. تعذّر تنفيذ طلبات الشبكة أثناء تحديث endpoint. أحد الحلول هو لتتبُّع حالة endpoint في ملف تعريف ارتباط لتحديد ما إذا كان الخادم يحتاج إلى أحدث التفاصيل أم لا.

تؤدي كل الخطوات المذكورة أعلاه إلى تنفيذ رسائل الدفع بشكل كامل على الويب في Chrome 46. لا تزال هناك ميزات محدّدة ستسهّل الأمور (مثل واجهة برمجة تطبيقات قياسية لتشغيل رسائل الدفع)، ولكن هذا الإصدار يتيح لك ابدأ في إنشاء رسائل فورية في تطبيقات الويب لديك اليوم.

كيفية تصحيح الأخطاء في تطبيق الويب

أثناء تنفيذ الرسائل الفورية، ستظهر الأخطاء في مكان من مكانَين: صفحتك. أو عامل الخدمة.

يمكن تصحيح الأخطاء في الصفحة باستخدام DevTools: لتصحيح أخطاء مشغّل الخدمات المشكلات، لديك خياران:

  1. انتقل إلى chrome://inspect > مشغِّلو الخدمات: لا توفر طريقة العرض هذه من المعلومات غير عاملي الخدمة العاملين حاليًا.
  2. انتقل إلى chrome://serviceworker-internals ومن هنا يمكنك عرض عاملي الخدمة، والاطّلاع على الأخطاء، إن وجدت. هذه الصفحة مؤقتًا إلى أن تتوفّر ميزة مماثلة في "أدوات مطوّري البرامج".

من أفضل النصائح التي يمكنني تقديمها لأي شخص جديد في مجال عمال الخدمة هي استخدام مربع الاختيار المسمى "فتح نافذة أدوات مطوري البرامج وإيقاف تنفيذ JavaScript مؤقتًا عند بدء تشغيل عامل الخدمة لتصحيح الأخطاء". سيضيف مربع الاختيار هذا نقطة توقف في بداية مشغّل الخدمات وإيقاف التنفيذ مؤقتًا، يتيح لك ذلك أو تتابعه أو تتنقل فيه إلى نص عامل الخدمة الخاص بك ومعرفة ما إذا كنت قد ضربت المشكلات.

لقطة شاشة تعرض مكان وضع علامة في مربّع اختيار تنفيذ الإيقاف المؤقت على Serviceworker-internals

إذا بدا أنّ هناك مشكلة بين خدمة "المراسلة عبر السحابة الإلكترونية من Firebase" وحدث الدفع لدى مشغّل الخدمات، فلن يكون هناك الكثير مما يمكنك القيام به لتصحيح المشكلة حيث لا توجد طريقة لمعرفة ما إذا كان Chrome قد تلقى أي شيء الشيء الرئيسي الذي يجب التأكد منه هو أن تكون الاستجابة من خدمة "المراسلة عبر السحابة الإلكترونية من Firebase" ناجحة عندما يجري الخادم طلب بيانات من واجهة برمجة التطبيقات. ستظهر الصورة شيء مثل:

{"multicast_id":1234567890,"success":1,"failure":0,"canonical_ids":0,"results":[{"message_id":"0:1234567890"}]}

لاحِظ الردّ "success": 1. وإذا لاحظت إخفاقًا بدلاً من ذلك، فإن ذلك إلى وجود خطأ في رقم تعريف التسجيل في "المراسلة عبر السحابة الإلكترونية من Firebase" لا يتم إرسال رسالة إلى Chrome.

تصحيح أخطاء مشغِّلي الخدمات على Chrome لنظام Android

في الوقت الحالي، ليس من الواضح أنّ تصحيح أخطاء موظفي الخدمة على Chrome لنظام Android. عليك الانتقال إلى chrome://inspect، والعثور على جهازك، والبحث عن عنصر قائمة باسم "Worker pid:...." الذي يحتوي على عنوان URL لخدمتك عامل.

لقطة شاشة تعرض مكان عمل عاملي الخدمة في عمليات فحص Chrome

تجربة المستخدم للإشعارات الفورية

يعمل فريق Chrome على إعداد مستند يعرض أفضل الممارسات لـ "تجربة المستخدم" بالإشعارات الفورية بالإضافة إلى مستند يتناول بعض الحالات الهامشية عند التعامل مع الإشعارات الفورية.

مستقبل ميزة "المراسلة الفورية" على Chrome والويب المفتوح

يتناول هذا القسم بعض التفاصيل التي تحيط ببعض برامج الأجزاء المحددة لعملية التنفيذ هذه التي ينبغي أن تكون على دراية بها وكيف عن عمليات تنفيذ المتصفّحات الأخرى.

بروتوكول Web Push ونقاط النهاية

يكمن جمال معيار Push API في أنك يجب أن تكون قادرًا على أخذ نقطة النهاية، مرِّرها إلى خادمك وأرسِل الإشعارات من خلال تطبيق بروتوكول Web Push.

بروتوكول Web Push هو معيار جديد يمكن لمزودي خدمة الدفع تنفيذه، ما يسمح للمطوّرين بعدم القلق بشأن هوية مقدِّم خدمة إرسال الرسائل الإلكترونية. تشير رسالة الأشكال البيانية هو أن هذا يتجنب الحاجة إلى الاشتراك للحصول على مفاتيح واجهة برمجة التطبيقات والإرسال بشكل خاص البيانات المنسقة، كما هو الحال مع خدمة "المراسلة عبر السحابة الإلكترونية من Firebase".

كان Chrome أول متصفح ينفِّذ واجهة برمجة تطبيقات Push ولم يتم تفعيل خدمة "المراسلة عبر السحابة الإلكترونية من Firebase" من بروتوكول Web Push، الأمر الذي يجعل Chrome gcm_sender_id وتحتاج إلى استخدام واجهة برمجة التطبيقات المريحة لخدمة "المراسلة عبر السحابة الإلكترونية من Firebase".

يتمثّل هدف Chrome في استخدام بروتوكول Web Push مع متصفّح Chrome و"المراسلة عبر السحابة الإلكترونية من Firebase".

وحتى ذلك الحين، عليك رصد نقطة النهاية &quot;https://fcm.googleapis.com/fcm/send&quot; ومعالجتها بشكل منفصل عن نقاط النهاية الأخرى، أي تنسيق بيانات الحمولة بطريقة محددة وإضافة مفتاح التفويض.

كيف يمكن تطبيق بروتوكول Web Push؟

يعمل Firefox Nightly حاليًا على إصدار التحديث، وسيكون على الأرجح المتصفّح الأول. لتطبيق بروتوكول Web Push.

الأسئلة الشائعة

أين المواصفات؟

https://slightlyoff.github.io/ServiceWorker/spec/service_worker/ https://w3c.github.io/push-api/ https://notifications.spec.whatwg.org/

هل يمكنني منع تلقّي إشعارات مكرَّرة إذا كان للحضور على الويب مصادر متعددة أو إذا كان لديّ حضور على الويب وفي التطبيقات الأصلية؟

لا يتوفّر حل لهذه المشكلة في الوقت الحالي، ولكن يمكنك متابعة مستوى التقدّم على Chromium.

السيناريو المثالي هو الحصول على نوع من المعرف لجهاز المستخدم ثم على الخادم، تطابق معرّفات الاشتراك في التطبيق الأصلي وتطبيق الويب أن تقرر أي رف تريد إرسال رسالة فورية إليه. يمكنك القيام بذلك عبر حجم الشاشة، طراز الجهاز، ومشاركة مفتاح تم إنشاؤه بين تطبيق الويب والتطبيق الأصلي، ولكن لكل نهج إيجابيات وسلبيات.

لماذا أحتاج إلى gcm_sender_id؟

وهذا الإجراء مطلوب حتى يتسنى لكل من Chrome وOpera لنظام التشغيل Android ومتصفّح Samsung تستخدم واجهة برمجة تطبيقات "المراسلة عبر السحابة الإلكترونية من Firebase" (FCM). الهدف هو استخدام بروتوكول Web Push Protocol عند الانتهاء من المعيار ويمكن لخدمة "المراسلة عبر السحابة الإلكترونية من Firebase" دعمه.

لمَ لا يتم استخدام Web Sockets أو Server-Sent Events (الأحداث المُرسَلة من الخادم) (EventSource)؟

تتمثل ميزة استخدام رسائل الدفع في أنه حتى إذا تم إغلاق الصفحة، فسيتم عامل الخدمة، وسيكون قادرًا على عرض إشعار. مآخذ الويب ويتم إغلاق الاتصال بـ EventSource عند إغلاق الصفحة أو المتصفح.

ماذا لو لم أكن بحاجة إلى عرض الأحداث في الخلفية؟

في حال لم تكن بحاجة إلى التسليم في الخلفية، تُعدّ Web Sockets خيارًا رائعًا.

متى يمكنني استخدام الإشعارات الفورية بدون عرض إشعارات (أي الدفع التلقائي في الخلفية)؟

ليس هناك جدول زمني لموعد توفر ذلك حتى الآن، ولكن هناك أعتزم تنفيذ المزامنة في الخلفية ورغم أنّه لم يتم تحديده أو تحديد مواصفاته، هناك بعض المناقشات حول تفعيل إرسال تلقائي مع مزامنة في الخلفية

لماذا يتطلّب ذلك استخدام HTTPS؟ كيف يمكنني تفادي ذلك أثناء التطوير؟

يطلب مشغّلو الخدمة مصادر آمنة لضمان استخدام النص البرمجي لمشغّل الخدمات من الأصل المقصود ولا تأتي من وسيط هجوم. ويعني هذا في الوقت الحالي استخدام HTTPS على المواقع المباشرة، على الرغم من أن المضيف المحلي سيستخدم العمل أثناء التطوير.

كيف يبدو دعم المتصفّح؟

يتوافق متصفّح Chrome مع إصداره الثابت، كما تعمل Mozilla على الضغط باستمرار على المتصفِّح في Firefox Nightly. لمزيد من المعلومات، راجِع تنفيذ الخطأ في واجهة برمجة التطبيقات Push API. ويمكنك أيضًا تتبّع تنفيذ الإشعارات الخاصة بهم هنا.

هل يمكنني إزالة إشعار بعد فترة زمنية معيّنة؟

يتعذّر تنفيذ ذلك في الوقت الحالي، ولكنّنا ننوي إضافة دعم قائمة بالإشعارات المرئية حاليًا إذا كانت لديك حالة استخدام لتحديد لانتهاء صلاحية الإشعار بعد أن يتم عرضه، يسعدنا أن نعرف ما هذا، لذا يرجى إضافة تعليق وسنعيد إرساله إلى فريق Chrome.

إذا كنت تريد فقط إيقاف إرسال الإشعارات الفورية إلى المستخدم بعد فترة زمنية معينة، ولا يهمني المدة التي يظل فيها الإشعار إذًا، يمكنك استخدام معلمة وقت FCM للعيش (ttl)، مزيد من المعلومات

ما هي قيود إرسال الرسائل الفورية في Chrome؟

هناك بعض القيود الموضحة في هذه المشاركة:

  • يؤدي استخدام Chrome لـ "إدارة الشؤون التجارية والعقود" كخدمة إرسال الملفات إلى إنشاء عدد من العمليات متطلبات المشروع. نحن نعمل معًا لمعرفة ما إذا كان من الممكن إزالة بعضها المستقبل.
  • عليك إظهار إشعار عندما تتلقّى رسالة فورية.
  • يحذر Chrome على سطح المكتب من أنّه في حال عدم تشغيل Chrome، يجب دفع الرسائل المستلمون. يختلف ذلك عن نظام التشغيل ChromeOS وAndroid حيثما يتم إرسال رسائل الدفع دائمًا.

ألا يجب استخدام واجهة Permissions API؟

تشير رسالة الأشكال البيانية واجهة برمجة التطبيقات Permission API في Chrome، ولكنها لن تكون متوفرة بالضرورة في جميع المتصفحات. مزيد من المعلومات

لماذا لا يفتح Chrome علامة التبويب السابقة عند النقر على إشعار؟

لا تؤثِّر هذه المشكلة إلا في الصفحات التي لا تتحكّم بها خدمة في الوقت الحالي. عامل. يمكنك الاطّلاع على المزيد من المعلومات هنا.

ماذا لو كان الإشعار قديمًا بحلول الوقت الذي تلقّى فيه جهاز المستخدم الدفعة؟

عليك دائمًا إظهار إشعار عندما تتلقّى رسالة فورية. في السيناريو الذي تريد إرسال إشعار فيه، ولكنه يكون مفيدًا فقط لفترة زمنية معيّنة، يمكنك استخدام "time_to_live" مَعلمة على "إدارة الشؤون التجارية والعقود" حتى لا ترسل خدمة "المراسلة عبر السحابة الإلكترونية من Firebase" رسالة الدفع إذا مرت وقت انتهاء الصلاحية.

يمكنك الاطّلاع على مزيد من التفاصيل هنا.

ماذا يحدث إذا أرسلت 10 رسائل فورية ولكن أريد أن يتلقّى الجهاز رسالة واحدة فقط؟

تحتوي ميزة "المراسلة عبر السحابة الإلكترونية من Firebase" على "مفتاح_تصغير" يمكنك استخدامها لإبلاغ خدمة "المراسلة عبر السحابة الإلكترونية من Firebase" باستبدال أي مَعلمة في انتظار المراجعة التي تحتوي على نفس "تصغير_مفتاح"، مع الرسالة الجديدة.

يمكنك الاطّلاع على مزيد من التفاصيل هنا.