Skip to content

🐛 Bug Report: Framework doesn't allow sending Rich Push Messages through Firebase Cloud Messaging #9489

@paul-github-1

Description

@paul-github-1

📜 Description

Context: novu/framework, in a Bridge app, when defining a workflow step of type "push"

Problem 1: push schema is limited to only two fields

The schema of a push step in (node_modules/@novu/framework/dist/esm/health-check.types-_.d.ts), is limited to only two fields: title and body. This is also the case in the dashboard when trying to create a push step.

But the schema also allows you to add provider objects with known provider fields, which leads to problem #2:

Problem 2: providerSchema for FCM might be outdated

For example, for FCM, you're allowed to pass a notification object among other fields, but it looks like the schema is outdated (not fully updated since the move to FCM HTTP V1?).

  • Notice that the providerSchemas for fcm does not have fcmOptionsor fcm_options field for example.

  • See this line for example leading to a non-existent fcm docs page (404).

  • The provider schema doesn't have the fields of a real fcm notification object like AndroidConfig, WebpushConfig, etc.

Problem 3: You CANNOT override what Novu sends to FCM for Webpush.

When using the novu / framework (workflow as code) and defining a push step, no matter what you pass to novu as fields, Novu will still send only title + body. Any other values will just be ignored. Pass any other value and it will be ignored. Here, I'm referring to a native notification, not a data notification.

So, of course you can pass a data object and interpret it in your service worker, but this is HIGHLY unreliable since the quirks of iOS (webpush through PWA) will not always wake up the service worker, etc. Unreliable in chrome too.

So, the safest path for webpush is a standard notification.

But Novu will always send only title + body --> no Link! So when clicking the notification, the device doesn't know what to do. iOS will open the PWA without deep linking, Chrome will not always open the website. The device is confused: where to send the user?

Problem 4: Using Passthrough object to deep merge the body that Novu sends to FCM does not work

Using passthrough object is supposed to push extra fields in the request body does not work either. Novu will still send only title + body, no link, no fcmOptions, no icon, no badge, or anything like that.

Solution I ended up using: Creating a custom step and sending notifications to FCM myself

I had to build a custom step to be able to send standard webpush notifications through FCM. This is not ideal since it doesn't allow you to have proper novu logs, proper channel-based and per-workflow notification settings for users. Very hacky.

But it works! As soon as I did send directly through FCM, the full rich Webpush Notification reaches FCM which sends it to browsers in a RELIABLE way. iOS clicks on notifications is able to open a deep link, so does Chrome desktop, etc.

👟 Reproduction steps

dependencies:

  • "@novu/framework": "^2.8.0"
  • "novu": "^2.7.0"

In a bridge app, in a workflow definition, try adding a push step:

Here are the two exact shapes we tried inside the push step, both resulted in Firebase receiving only the plain notification.title/body (no data, no webpush, no fcmOptions), so the service worker never saw the rest of the payload.

1. Provider override (schema-compliant fields only):

await step.push('chat-msg-webpush', async () => ({
  subject: 'New message',
  body: 'Preview snippet',
  data: {
    actionUrl: 'https://example.com/chat/123',
    chatId: '123',
    workflow: 'chats_new_message',
    subject: 'New message',
    body: 'Preview snippet',
    icon: 'https://cdn.example.com/avatar.png',
    badge: 'https://cdn.example.com/badge.png',
    tag: 'chat-msg-123',
    chatTitle: 'Support',
  },
}), {
  providers: {
    fcm: ({ outputs }) => ({
      notification: {
        title: outputs.subject,
        body: outputs.body,
        icon: outputs.data.icon,
        badge: outputs.data.badge,
        tag: outputs.data.tag,
      },
      data: outputs.data,
    }),
  },
});

2. Provider override + _passthrough HTTP v1 envelope (to include webpush/fcmOptions):

await step.push('chat-msg-webpush', async () => ({
  subject: 'New message',
  body: 'Preview snippet',
  data: {
    actionUrl: 'https://example.com/chat/123',
    chatId: '123',
    workflow: 'chats_new_message',
    subject: 'New message',
    body: 'Preview snippet',
    icon: 'https://cdn.example.com/avatar.png',
    badge: 'https://cdn.example.com/badge.png',
    tag: 'chat-msg-123',
    chatTitle: 'Support',
  },
}), {
  providers: {
    fcm: ({ outputs }) => ({
      notification: {
        title: outputs.subject,
        body: outputs.body,
        icon: outputs.data.icon,
        badge: outputs.data.badge,
        tag: outputs.data.tag,
      },
      data: outputs.data,
      _passthrough: {
        body: {
          message: {
            notification: {
              title: outputs.subject,
              body: outputs.body,
            },
            data: outputs.data,
            webpush: {
              notification: {
                title: outputs.subject,
                body: outputs.body,
                icon: outputs.data.icon,
                badge: outputs.data.badge,
                tag: outputs.data.tag,
              },
              data: outputs.data,
              fcmOptions: {
                link: outputs.data.actionUrl,
              },
            },
            fcmOptions: {
              link: outputs.data.actionUrl,
            },
          },
        },
      },
    }),
  },
});

👍 Expected behavior

Full rich notification reaching the service worker.

👎 Actual Behavior with Screenshots

Don't have screenshots but I can tell you I struggled with this for about 4 days.

In both cases, Novu reported “success,” but the actual payload that reached FCM (per the service worker) was just:

{
  "notification": {
    "title": "...",
    "body": "..."
  }
}

Novu version

2.3.0

npm version

No response

node version

No response

📃 Provide any additional context for the Bug.

Feel free to tell me if this whole thing is a skill issue. I'd love to be able to send a full FCM standard notification through Novu for WebPush (and to Android / iOS app in the future). As of now, I'm sending calling FCM directly from the Bridge App in a Novu custom step.

👀 Have you spent some time to check if this bug has been raised before?

  • I checked and didn't find a similar issue

🏢 Have you read the Contributing Guidelines?

Are you willing to submit PR?

None

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions