NevTan Engage

Features

Email MarketingSMS MarketingAutomations

Solutions

eCommerceSaaS & AppsB2B Lead GenAgencies

Resources

BlogHelp CenterDocumentationEmail TemplatesAPIFAQs

Company

AboutPricingContactNevTan

Legal

Data Processing AgreementSubprocessor ListAI & Data Usage PolicySecurity & Compliance

© 2026 NevTan Engage. All rights reserved.

Cookie Policy | Terms and Conditions | Privacy Policy

Skip to main content

Channels & Automation

Email Marketing

Beautiful campaigns that convert

SMS Marketing

Reach customers instantly

Automations

Visual drag-and-drop workflows

By Industry

eCommerce

Boost sales & reduce cart abandonment

SaaS & Apps

Onboard & retain users at scale

B2B Lead Gen

Nurture leads to conversion

Agencies

White-label for your clients

Plans & Pricing

Pricing Plans

Simple, transparent pricing

Learn & Build

Blog

Marketing tips and best practices

Email Marketing Templates

Ready-to-use campaign layouts

Documentation

Guides for every feature in Engage

API

Build custom integrations

About Us

Contact Us

LoginStart Free Trial(No card)

Getting started

  • Introduction
  • Create your account
  • Signing in
  • Your dashboard & navigation

Contacts

  • Contacts & profiles
  • Lists
  • Importing contacts
  • Segments
  • Suppression list

Campaigns

  • Campaigns overview
  • Create & send a campaign
  • Reading a campaign's results

Templates

  • Template library
  • Create with AI
  • The template editor
  • Template approval

Automations

  • Built-in flows
  • Custom flows

Analytics

  • Contact Growth
  • Campaign Reports
  • Automation Reports
  • Metrics glossary

Integrations

  • Webhooks
  • Push Notifications: setup
  • API Keys

Account & billing

  • Your profile
  • Custom sending domains
  • Plans & pricing
  • Billing, usage & invoices
  • Team & roles

Administration

  • Admin overview
  • Campaign & template review
  • Customers & packages

Documentation/Integrations

Push Notifications: setup

Get a Firebase project, hand Engage the key, and start collecting device tokens from your site.

Push has two halves. Firebase does the delivering — you own the project and the keys. Engage decides who gets what and when. This page connects the two, then gets your site sending device tokens in.

ℹ️

Roughly 20 minutes, most of it in the Firebase console. You need someone who can add a file to your website and someone who can edit the Engage server config.

1. Create the Firebase project

1

Open the Firebase console

Go to console.firebase.google.com and click Add project. If you already have one for this brand, use it — one project per brand, not one per environment.

2

Add a Web app

In Project settings → General → Your apps, click the web icon (</>). Name it and register. Firebase shows a firebaseConfig object — copy it, your site needs it in step 4.

3

Generate a Web Push certificate

Project settings → Cloud Messaging → Web configuration → Web Push certificates → Generate key pair. This is the VAPID key. Your site needs it; Engage does not.

2. Get the service account JSON

This is the file Engage needs. It lets Engage send on your project's behalf.

1

Open Service accounts

Project settings → Service accounts → Firebase Admin SDK.

2

Generate a new private key

Click Generate new private key, then Generate key. A .json file downloads. This is the only copy — Firebase will not show it again.

⚠️

That file is a credential with full send rights on your project. Do not commit it to a repository, paste it into a ticket, or email it. You upload it directly to Engage in the next step, so it never needs to travel anywhere else.

It should look like this — type must be service_account:

json
{
  "type": "service_account",
  "project_id": "your-project-id",
  "private_key_id": "…",
  "private_key": "-----BEGIN PRIVATE KEY-----\n…\n-----END PRIVATE KEY-----\n",
  "client_email": "firebase-adminsdk-xxxxx@your-project-id.iam.gserviceaccount.com",
  "client_id": "…",
  "token_uri": "https://oauth2.googleapis.com/token"
}

3. Upload it to Engage

No server config and no deploy. In Engage open Push Notifications, click the settings icon, and upload the .json file from step 2.

1

Open Firebase setup

Push Notifications → the settings icon in the top right. If push has never been set up, the banner on that screen links straight there.

2

Choose the file

Engage checks it before saving — first that it is a service account key at all, then by asking Google to issue a token with it. Expect a second's pause; that pause is the check.

3

Confirm what it says

Once connected you see the project, the service account address and the key ID. Those are enough to tell two keys apart, which is what you need when a rotation does not seem to have landed.

⚠️

A key that has been deleted or revoked in the Firebase console is refused here, with Google's reason. That is deliberate: a revoked key parses perfectly, so without the live check it would save cleanly and fail during your first campaign.

The key is encrypted before it is stored and is never shown again — there is nothing to reveal, and no endpoint returns it. To rotate, generate a new key in Firebase and upload it over the old one; to stop sending, disconnect.

ℹ️

You need the settings permission to connect a project, so owners and admins can do this and editors cannot. An API key can never do it at all.

There is no environment to choose

Engage used to keep separate stage and prod Firebase credentials, and a send had to pick one. It does not any more: your uploaded project *is* the choice. If you want to keep test and live traffic apart, use two Engage accounts with a different Firebase project in each.

SettingDefaultWho sets it
Firebase keynoneYou, on the Firebase setup panel
push_feature_enabledtrueAn operator, to turn push off across the whole deployment
push_providerreal FCMAn operator. mock simulates every send — it reports success and delivers nothing, so it belongs in local development and nowhere else
push_token_eventpush_notificationAn operator, only if that event name is already used for something else
ℹ️

Deployment-wide credentials in app.conf still work as a fallback for accounts that have not uploaded their own. They are operator-only and you should not need them — uploading takes precedence over anything configured there.

4. Add the service worker to your site

Web push needs a service worker at the root of your domain, so the file must be reachable at https://yoursite.com/firebase-messaging-sw.js — not in a subfolder. Put it in your public/ directory.

javascript
// public/firebase-messaging-sw.js
importScripts("https://www.gstatic.com/firebasejs/10.12.2/firebase-app-compat.js");
importScripts("https://www.gstatic.com/firebasejs/10.12.2/firebase-messaging-compat.js");

firebase.initializeApp({
  apiKey: "…",
  projectId: "your-project-id",
  messagingSenderId: "…",
  appId: "…",
});

firebase.messaging();
ℹ️

Those values are the firebaseConfig from step 1. They are public by design — they identify your project, they do not authorise sending. The service account from step 2 is the secret, and it never goes near the browser.

5. Ask for permission and collect the token

On your site, request notification permission and read the device token. Ask at a moment that makes sense — after a login or a deliberate opt-in click. A prompt on first page load is the fastest way to get permanently blocked.

javascript
import { initializeApp } from "firebase/app";
import { getMessaging, getToken } from "firebase/messaging";

const app = initializeApp(firebaseConfig);
const messaging = getMessaging(app);

export async function enablePush(user) {
  if (Notification.permission === "denied") return null;
  if ((await Notification.requestPermission()) !== "granted") return null;

  const token = await getToken(messaging, {
    vapidKey: "YOUR_WEB_PUSH_CERTIFICATE_KEY",
  });
  if (!token) return null;

  await sendTokenToEngage(user, token);
  return token;
}

6. Send the token to Engage

There is no push-specific endpoint to call. You send an ordinary event named push_notification carrying the token, and Engage mirrors it into the device table bound to that contact. That is the whole integration.

javascript
async function sendTokenToEngage(user, token) {
  await fetch("https://api.engage.nevtan.com/api/v1/events", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "X-App-Id": "app_...",          // Settings → Integrations → Setup
      "X-App-Secret": "sk_live_...",
    },
    body: JSON.stringify({
      event_type: "push_notification",
      user: { email: user.email },     // required — this is the identity
      properties: {
        device_token: token,
        platform: "desktop",           // "ios" | "android" | "desktop"
      },
    }),
  });
}
⚠️

Fire this on every launch, not just the first time. Device tokens rotate silently — the browser reissues them and never tells you the old one died. A site that registers once ends up with a list of addresses that quietly stop working.

FieldNotes
event_typeMust match push_token_event (default push_notification)
user.emailRequired. Contacts are identified by email; without it the event is rejected
properties.device_tokentoken, push_token, fcm_token and registration_token are also accepted. Anything under 20 characters is ignored as a placeholder
properties.platformSend it explicitly. iPadOS reports a Mac user agent, so an iPad guessed from the user agent lands in desktop

The endpoint always answers HTTP 200 — the outcome is in the body, so check success:

json
{ "success": true, "profile_id": "000000000000000000000001", "error": null }

7. Send your first push

1

Check the device arrived

Open Push Notifications → Devices. Your browser should be listed as active. If it is not, the event did not reach Engage — check success in the response above.

2

Send to yourself

Open Compose, write a title and body, and use the device filter to target only your own device before sending to anyone else.

3

Then target a segment

Any segment works. "Subscribed to push in the last 30 days" is an ordinary segment condition, because the token arrived as an ordinary event.

When it does not work

SymptomCause
`SENDER_ID_MISMATCH` on every deviceYour devices were registered against a different Firebase project than the key you uploaded. Usually the site is still minting tokens with its old firebaseConfig — check the project id in firebase-messaging-sw.js against the one shown on the Firebase setup panel
Devices list stays emptyThe event is not arriving. Check success in the response, that user.email is present, and that the event name matches push_token_event
Sends report success, nothing arrivespush_provider = mock is set. It simulates every send and contacts no device
Token rejected as too shortUnder 20 characters — a placeholder or a truncated copy/paste
Devices go inactive over timeNormal. Google reports tokens as gone when someone clears site data or revokes permission, and Engage retires them so the list stays clean
ℹ️

accepted in a send result means the push service took the message, not that a handset received it. No push platform reports actual delivery back, so treat that number as "handed over", not "delivered".

Previous

Webhooks

Next

API Keys

Still need a hand?

Our support team usually replies within one business day.

Contact support

On this page

  • 1. Create the Firebase project
  • 2. Get the service account JSON
  • 3. Upload it to Engage
  • 4. Add the service worker to your site
  • 5. Ask for permission and collect the token
  • 6. Send the token to Engage
  • 7. Send your first push
  • When it does not work