אירועי דחיפה

בשלב הזה כבר טיפלנו בהרשמה של משתמש ובשליחת הודעה. השלב הבא הוא לקבל את ההודעה הזו במכשיר של המשתמש ולהציג התראה (כמו גם כל הודעה אחרת) העבודה שאולי נרצה לעשות).

אירוע ה-Push

כשמתקבלת הודעה, התוצאה היא שליחת אירוע דחיפה ב-Service Worker.

הקוד להגדרת האזנה לאירוע Push צריך להיות די דומה לכל אירוע אחר צריך לכתוב ב-JavaScript:

self.addEventListener('push', function(event) {
    if (event.data) {
    console.log('This push event has data: ', event.data.text());
    } else {
    console.log('This push event has no data.');
    }
});

הקטע המוזר ביותר בקוד הזה עבור רוב המפתחים שלא מכירים את קובצי השירות (service worker) הוא self מותאם אישית. המונח self נמצא בשימוש נפוץ ב-Web Workers, שהם קובצי שירות (service worker). המונח self מתייחס ההיקף הגלובלי, בערך כמו window בדף אינטרנט. אבל לגבי עובדי אינטרנט ועובדי שירות, המונח self מתייחס לעובד עצמו.

בדוגמה שלמעלה, אפשר לחשוב על self.addEventListener() כעל הוספה של האזנה לאירוע את ה-Service Worker עצמו.

בתוך הדוגמה של אירוע הדחיפה, אנחנו בודקים אם יש נתונים ומדפיסים משהו למסוף.

יש דרכים נוספות לנתח נתונים מאירוע Push:

// Returns string
event.data.text()

// Parses data as JSON string and returns an Object
event.data.json()

// Returns blob of data
event.data.blob()

// Returns an arrayBuffer
event.data.arrayBuffer()

רוב האנשים משתמשים ב-json() או ב-text() בהתאם לציפיות שלהם מהאפליקציה.

הדוגמה הזו מדגימה איך להוסיף האזנה לאירוע Push, ואיך לגשת לנתונים, אבל חסרים שני חלקים חשובים מאוד של פונקציונליות. לא מוצגת התראה לא משתמש ב-event.waitUntil().

אני רוצה לחכות עד

אחד הדברים שחשוב להבין לגבי Service Worker הוא שיש לכם מעט שליטה שהקוד של Service Worker ירוץ. הדפדפן מחליט מתי להוציא אותו ממצב שינה ומתי לסיים אותו. הדרך היחידה לומר לדפדפן, "היי, אני ממש עסוקה בדברים חשובים דברים", הוא להעביר הבטחה לשיטה event.waitUntil(). עכשיו הדפדפן ימשיכו לפעול עד שההבטחה שהעברתם תפוג.

כשמדובר באירועי Push, יש דרישה נוספת להצגת התראה לפני ההבטחה שהעברת נפתר.

דוגמה בסיסית להצגת התראה:

self.addEventListener('push', function(event) {
    const promiseChain = self.registration.showNotification('Hello, World.');

    event.waitUntil(promiseChain);
});

התקשרות אל self.registration.showNotification() היא האמצעי להצגת התראה ל: למשתמש ומחזירה הבטחה שתסתיים לאחר הצגת ההתראה.

כדי לשמור על דוגמה זו ברורה ככל האפשר, הקציתי את ההבטחה הזו שנקרא promiseChain. לאחר מכן הסכום מועבר אל event.waitUntil(). ברור לי שזה מפורט מאוד, אבל ראיתי כמה בעיות שהגיעו לשיא בעקבות הבנה שגויה של מה צריך להעביר אל waitUntil() או כתוצאה מהבטחה לא תקינה .

דוגמה מורכבת יותר עם בקשת רשת לנתונים ומעקב אחר אירוע הדחיפה באמצעות ניתוח הנתונים עשוי להיראות כך:

self.addEventListener('push', function(event) {
    const analyticsPromise = pushReceivedTracking();
    const pushInfoPromise = fetch('/api/get-more-data')
    .then(function(response) {
        return response.json();
    })
    .then(function(response) {
        const title = response.data.userName + ' says...';
        const message = response.data.message;

        return self.registration.showNotification(title, {
        body: message
        });
    });

    const promiseChain = Promise.all([
    analyticsPromise,
    pushInfoPromise
    ]);

    event.waitUntil(promiseChain);
});

כאן אנחנו קוראים לפונקציה שמחזירה מובטחת pushReceivedTracking(), לצורך הדוגמה, נוכל להעמיד פנים שבקשת רשת אל ספק שירותי הניתוח שלנו. אנחנו גם שולחים בקשת רשת, תשובה והצגת הודעה עם נתוני התגובות של הכותרת בהודעה.

אנחנו יכולים להבטיח ש-Service Worker יישאר פעיל בזמן ששתי המשימות האלה מתבצעות על ידי שילוב את ההבטחות האלה בעזרת Promise.all(). ההבטחה שמתקבלת מועברת אל event.waitUntil() כלומר, הדפדפן ימתין עד ששני ההבטחות יסתיימו לפני שיבדוק שהתראה מוצג ומסיים את Service Worker.

הסיבה שבגללה אנחנו חוששים לגבי waitUntil() וכיצד להשתמש בו היא בעיות נפוצות שמפתחים נתקלים בהן הן שכששרשרת ההבטחה שגויה או לא תקינה, Chrome הצגת 'ברירת המחדל' התראה:

תמונה של התראת ברירת המחדל ב-Chrome

ב-Chrome יוצג רק הכיתוב 'האתר הזה עודכן ברקע'. התראה על כך מתקבלת הודעת דחיפה ובאירוע ה-Push ב-Service Worker לא מופיע התראה אחרי שההבטחה שהועברה אל event.waitUntil() הסתיימה.

הסיבה העיקרית לכך שמפתחים נתקלים בזה היא שהקוד שלהם קוראים בדרך כלל ל-self.registration.showNotification() אבל לא כל דבר שמבטיח שהוא יחזור. פעולה זו מובילה לסירוגין להתראת ברירת המחדל שמוצגת. לדוגמה, אפשר להסיר את ההחזרה של self.registration.showNotification() בדוגמה שלמעלה, ואנחנו מסתכנים בכך התראה.

self.addEventListener('push', function(event) {
    const analyticsPromise = pushReceivedTracking();
    const pushInfoPromise = fetch('/api/get-more-data')
    .then(function(response) {
        return response.json();
    })
    .then(function(response) {
        const title = response.data.userName + ' says...';
        const message = response.data.message;

        self.registration.showNotification(title, {
        body: message
        });
    });

    const promiseChain = Promise.all([
    analyticsPromise,
    pushInfoPromise
    ]);

    event.waitUntil(promiseChain);
});

אתם יכולים לראות כמה קל לפספס.

חשוב לזכור – אם מופיעה ההודעה הזו, צריך לבדוק את שרשרת ההבטחה ואת event.waitUntil().

בקטע הבא נבחן מה אפשר לעשות כדי לעצב התראות איזה תוכן אנחנו יכולים להציג.

מה השלב הבא?

שיעורי Lab קוד