Всегда выдает ошибку регистрации при подписке push-уведомлений - PullRequest
2 голосов
/ 18 июня 2019

Я работаю над решениями, с помощью которых я могу отправлять push-уведомления на рабочем столе подписанным клиентам.

Я создал базовое решение, в котором всякий раз, когда пользователь нажимает кнопку, я спрашиваю пользователя, хотят ли они разрешить уведомления для моегоприложение или нет!

Я получаю сообщение об ошибке "Ошибка регистрации - отказано в разрешении" каждый раз, когда я нажимаю кнопку в первый раз.

Так что я не могучтобы получить необходимые конечные точки для сохранения в бэкэнде

Вот мой код

index.html

    <html>
       <head>
          <title>PUSH NOT</title>
          <script src="index.js"></script>
       </head>
       <body>
          <button onclick="main()">Ask Permission</button>
       </body>
    </html>

index.js

const check = () => {
  if (!("serviceWorker" in navigator)) {
    throw new Error("No Service Worker support!");
  } else {
      console.log("service worker supported")
  }
  if (!("PushManager" in window)) {
    throw new Error("No Push API Support!");
  } else {
      console.log("PushManager worker supported")
  }

};

const registerServiceWorker = async () => {
  const swRegistration = await navigator.serviceWorker.register("/service.js?"+Math.random());
  return swRegistration;
};

const requestNotificationPermission = async () => {
  const permission = await window.Notification.requestPermission();

  // value of permission can be 'granted', 'default', 'denied'
  // granted: user has accepted the request
  // default: user has dismissed the notification permission popup by clicking on x
  // denied: user has denied the request.
  if (permission !== "granted") {
    throw new Error("Permission not granted for Notification");
  }
};

const main = async () => {
  check();
  const swRegistration = await registerServiceWorker();
  const permission = await requestNotificationPermission();
};
// main(); we will not call main in the beginning.

.js

// urlB64ToUint8Array is a magic function that will encode the base64 public key
// to Array buffer which is needed by the subscription option
const urlB64ToUint8Array = base64String => {
  const padding = "=".repeat((4 - (base64String.length % 4)) % 4);
  const base64 = (base64String + padding)
    .replace(/\-/g, "+")
    .replace(/_/g, "/");
  const rawData = atob(base64);
  const outputArray = new Uint8Array(rawData.length);
  for (let i = 0; i < rawData.length; ++i) {
    outputArray[i] = rawData.charCodeAt(i);
  }
  return outputArray;
};

const saveSubscription = async subscription => {
  console.log("Save Sub")
  const SERVER_URL = "http://localhost:4000/save-subscription";
  const response = await fetch(SERVER_URL, {
    method: "post",
    headers: {
      "Content-Type": "application/json"
    },
    body: JSON.stringify(subscription)
  });
  return response.json();
};
self.addEventListener("activate", async () => {
  try {
   const applicationServerKey = urlB64ToUint8Array(
      "BFPtpIVOcn2y25il322-bHQIqXXm-OACBtFLdo0EnzGfs-jIGXgAzjY6vNapPb4MM1Z1WuTBUo0wcIpQznLhVGM"
    );  
    const options = { applicationServerKey, userVisibleOnly: true };
    const subscription = await self.registration.pushManager.subscribe(options);
    console.log(JSON.stringify(subscription))
    const response = await saveSubscription(subscription);
  } catch (err) {
    console.log(err.code)
    console.log(err.message)
    console.log(err.name)
    console.log('Error', err)
  }
});

self.addEventListener("push", function(event) {
  if (event.data) {
    console.log("Push event!! ", event.data.text());
  } else {
    console.log("Push event but no data");
  }
});

Также я создал немного бэкэнда

const express = require("express");
const cors = require("cors");
const bodyParser = require("body-parser");
const webpush = require('web-push') 

const app = express();
app.use(cors());
app.use(bodyParser.json());

const port = 4000;

app.get("/", (req, res) => res.send("Hello World!"));

const dummyDb = { subscription: null }; //dummy in memory store

const saveToDatabase = async subscription => {
  // Since this is a demo app, I am going to save this in a dummy in memory store. Do not do this in your apps.
  // Here you should be writing your db logic to save it.
  dummyDb.subscription = subscription;
};

// The new /save-subscription endpoint
app.post("/save-subscription", async (req, res) => {
  const subscription = req.body;
  await saveToDatabase(subscription); //Method to save the subscription to Database
  res.json({ message: "success" });
});

const vapidKeys = {
  publicKey:
    'BFPtpIVOcn2y25il322-bHQIqXXm-OACBtFLdo0EnzGfs-jIGXgAzjY6vNapPb4MM1Z1WuTBUo0wcIpQznLhVGM',
  privateKey: 'mHSKS-uwqAiaiOgt4NMbzYUb7bseXydmKObi4v4bN6U',
}

webpush.setVapidDetails(
  'mailto:janakprajapati90@email.com',
  vapidKeys.publicKey,
  vapidKeys.privateKey
)

const sendNotification = (subscription, dataToSend='') => {
  webpush.sendNotification(subscription, dataToSend)
}

app.get('/send-notification', (req, res) => {
  const subscription = {endpoint:"https://fcm.googleapis.com/fcm/send/dLjyDYvI8yo:APA91bErM4sn_wRIW6xCievhRZeJcIxTiH4r_oa58JG9PHUaHwX7hQlhMqp32xEKUrMFJpBTi14DeOlECrTsYduvHTTnb8lHVUv3DkS1FOT41hMK6zwMvlRvgWU_QDDS_GBYIMRbzjhg",expirationTime:null,keys:{"p256dh":"BE6kUQ4WTx6v8H-wtChgKAxh3hTiZhpfi4DqACBgNRoJHt44XymOWFkQTvRPnS_S9kmcOoDSgOVD4Wo8qDQzsS0",auth:"CfO4rOsisyA6axdxeFgI_g"}} //get subscription from your databse here.
  const message = 'Hello World'
  sendNotification(subscription, message)

  res.json({ message: 'message sent' })
})

app.listen(port, () => console.log(`Example app listening on port ${port}!`));

Пожалуйста, помогите мне

Ответы [ 3 ]

0 голосов
/ 24 июня 2019

Я могу думать о трех причинах, по которым отказано в разрешении

1) ваш сайт не работает по протоколу https (включая localhost, который не включен по протоколу https), по умолчанию в chrome, насколько я знаю, блокируется уведомление на сайтах http. Если это так, нажмите на иконку информации рядом с URL, затем нажмите на настройки сайта, затем измените уведомления, чтобы спросить

2) если вы используете Safari, тогда safari использует устаревший интерфейс разрешения «Запрос», то есть значение возвращается не через обещание, а через обратный вызов, поэтому вместо

Notification.requestPermission().then(res => console.log(res)) 

это

Notification.requestPermission(res => console.log(res))

3) Настройки вашего браузера блокируют запрос уведомлений глобально, чтобы убедиться, что это не ваша проблема, запустите следующий код в консоли (на защищенном сайте https)

Notification.requestPermission().then(res => console.log(res))

если вы получаете окно с предупреждением, то проблема заключается в другом, если вы не убедитесь, что браузер не блокирует запросы на уведомления

0 голосов
/ 25 июня 2019

При нажатии кнопки разрешения я не знаю, почему не могу получить конечные точки

0 голосов
/ 24 июня 2019

Попробуйте следующий код:

index.js

const check = () => {
    if (!("serviceWorker" in navigator)) {
        throw new Error("No Service Worker support!");
    } else {
        console.log("service worker supported")
    }
    if (!("PushManager" in window)) {
        throw new Error("No Push API Support!");
    } else {
        console.log("PushManager worker supported")
    }

};

const saveSubscription = async subscription => {
    console.log("Save Sub")
    const SERVER_URL = "http://localhost:4000/save-subscription";
    const response = await fetch(SERVER_URL, {
        method: "post",
        headers: {
            "Content-Type": "application/json"
        },
        body: JSON.stringify(subscription)
    });
    return response.json();
};

const urlB64ToUint8Array = base64String => {
    const padding = "=".repeat((4 - (base64String.length % 4)) % 4);
    const base64 = (base64String + padding)
        .replace(/\-/g, "+")
        .replace(/_/g, "/");
    const rawData = atob(base64);
    const outputArray = new Uint8Array(rawData.length);
    for (let i = 0; i < rawData.length; ++i) {
        outputArray[i] = rawData.charCodeAt(i);
    }
    return outputArray;
};

const registerServiceWorker = async () => {
    return navigator.serviceWorker.register("service.js?"+Math.random()).then((swRegistration) => {
        console.log(swRegistration);
        return swRegistration;
    });
};

const requestNotificationPermission = async (swRegistration) => {
    return window.Notification.requestPermission().then(() => {
        const applicationServerKey = urlB64ToUint8Array(
            "BFPtpIVOcn2y25il322-bHQIqXXm-OACBtFLdo0EnzGfs-jIGXgAzjY6vNapPb4MM1Z1WuTBUo0wcIpQznLhVGM"
        );
        const options = { applicationServerKey, userVisibleOnly: true };
        return swRegistration.pushManager.subscribe(options).then((pushSubscription) => {
            console.log(pushSubscription);
            return pushSubscription;
        });
    });
};

const main = async () => {
    check();
    const swRegistration = await registerServiceWorker();
    const subscription = await requestNotificationPermission(swRegistration);
    // saveSubscription(subscription);
};

service.js

self.addEventListener("push", function(event) {
    if (event.data) {
        console.log("Push event!! ", event.data.text());
    } else {
        console.log("Push event but no data");
    }
});
...