pusher / push-notifications-web

Beams Browser notifications
MIT License
39 stars 19 forks source link

Publishing to user from server creates empty notification #106

Closed heymartinadams closed 2 years ago

heymartinadams commented 2 years ago

Issue

Chrome and Firefox are showing undefined as title, no body, and no icon in the notification.

CleanShot 2022-05-12 at 17 09 36@2x

even though I made sure that I did pass those values correctly to the backend API:

CleanShot 2022-05-12 at 17 10 09@2x

Replication

/api/push/send API

// Packages
import PushNotifications from '@pusher/push-notifications-server'

const PagesApiPushSend = async (req, res) => {

  const { title, message, userId } = req.body

  const beamsClient = new PushNotifications({
    instanceId: process.env.NEXT_PUBLIC_PUSHER,
    secretKey: process.env.PUSHER
  })

  const response = await beamsClient.publishToUsers([userId], {
    web: { notification: { title, body: message } }
  })

  return res.json({ data: response })
}

export default PagesApiPushSend
benw-pusher commented 2 years ago

Hi @heymartinadams You will need to add the title to the payload correctly:

const response = await beamsClient.publishToUsers([userId], {
    web: { notification: { title: title, body: message } }
  })

This should show the notification title correctly. If you continue to see 'undefined' could you share any custom notification handling set on the client? Here is the notification as displayed on my machine. image

heymartinadams commented 2 years ago

Hi @benw-pusher thank you for your response. I believe I added the payload correctly using ES6’ property value shorthand:

this...

const response = await beamsClient.publishToUsers([userId], {
  web: { notification: { title, body: message } }
})

...is the same as...

const response = await beamsClient.publishToUsers([userId], {
  web: { notification: { title: title, body: message } }
})

Just to be safe, I tried it without the shorthand, to the same effect. Also, I made sure that title and message contained the correct values (they did). So pretty sure that the issue isn’t on client-side, although let me include client code below to be sure.


Here’s how I’m handling push registration on the client:

// Packages
import { useState, useEffect } from 'react'
import * as PusherPushNotifications from '@pusher/push-notifications-web'

// `token`, `user` provided by app
const HooksPushInit = ({ token, user }) => {

  const [pushEnabled, setPushEnabled] = useState(null)

  useEffect(() => {
    if (user) {
      ;(async () => {
        const beamsClient = new PusherPushNotifications.Client({
          instanceId: process.env.NEXT_PUBLIC_PUSHER
        })

        const beamsTokenProvider = new PusherPushNotifications.TokenProvider({
          url: `/api/push/register`,
          queryParams: {
            userId: user?.userId
          },
          headers: {
            Accept: 'application/json',
            'Content-Type': 'application/json',
            ...(token ? { Authorization: `Bearer ${token}` } : {})
          }
        })

        beamsClient
          .start()
          .then(() => beamsClient.setUserId(user?.userId, beamsTokenProvider))
          .then(res => {
            console.log(res)

            setPushEnabled(true)
          })
      })()
    }
  }, [user])

  return { data: pushEnabled }
}

export default HooksPushInit

And push sending:

// Packages
import { useEffect } from 'react'
// Functions
import fetchApi from '#/fetch'

const HooksPushSendWelcomePushMsg = ({ pushEnabled, user }) => {
  useEffect(() => {
    if (pushEnabled) {
      ;(async () => await fetchApi({
        path: `/api/push/send`,
        data: {
          // `userId` gets passed through automatically via authentication
          title: `Congratulations 🎉`,
          message: `${
            user?.nameFirst ? `Hi ${user?.nameFirst}` : `Hey`
          }! You’ve successfully enabled reminders. This is how reminders appear.`
        }
      })
      )()
    }
  }, [pushEnabled])
}

export default HooksPushSendWelcomePushMsg
benw-pusher commented 2 years ago

Could you try manually constructing the notification content in your push api endpoint to ensure the issue is not with the payload generation there?

import PushNotifications from '@pusher/push-notifications-server'

const PagesApiPushSend = async (req, res) => {

  const { title, message, userId } = req.body

  const beamsClient = new PushNotifications({
    instanceId: process.env.NEXT_PUBLIC_PUSHER,
    secretKey: process.env.PUSHER
  })

  const response = await beamsClient.publishToUsers([userId], {
    web: { notification: { 
      title: `Congratulations 🎉`, 
      body: `Hey Martin! You’ve successfully enabled reminders. This is how reminders appear.` } }
  })

  return res.json({ data: response })
}

export default PagesApiPushSend

My testing hasn't been able to replicate the undefined issue you are experiencing so the library looks to be behaving ok.

heymartinadams commented 2 years ago

Hi @benw-pusher, apologies for not replying sooner, was busy completing a sprint.

After doing further digging, it looks like this error is caused because I’m using a third-party service worker (progressier.com). Will work it out with that service and will post here if we find a solution to this issue.

Thanks again!