Skip to main content
Tranthor sends push to your Android app through Firebase Cloud Messaging (FCM), using a key from your own Firebase project. Your app runs the Tranthor Android SDK, which tells Tranthor which phones belong to which customer and reports what happens to each push.
Mobile push is available per workspace. Ask us at support@tranthor.com to turn it on for yours. iOS is not available yet.

Before you start

You need:
  • A Firebase project with your Android app added to it (the app’s package name, for example com.example.shop).
  • The Tranthor Android SDK in your app, with its push module (below).
  • An Admin or Workspace manager role in Tranthor, to add the key.

1. Create a Firebase service-account key

  1. Open the Firebase console and select the project your app uses.
  2. Go to Project settings, then Service accounts.
  3. Select Generate new private key. Firebase downloads a JSON file. If Firebase says key creation is not allowed, see Troubleshooting.
Keep the file private. Anyone with it can send push to your app’s users. Do not commit it, email it or paste it into a chat.

2. Add the key in Tranthor

  1. In Tranthor, go to Settings, Mobile, Push.
  2. On the Android (FCM) card, select Add key.
  3. Enter your app’s application id (its package name) and choose the JSON file, or paste its contents.
  4. Select Save.
Tranthor checks the key with Google before it saves it. If Google refuses the key, nothing is saved and the dialog says why. The key stays on the Tranthor server and is never shown again; to change it, select Replace key. Once the key is saved, the card shows Healthy. Use Send test to send a test push to one phone of a customer: choose the customer, then one of their phones. A removed phone is dimmed and can’t be picked. A test push is labelled as a test and never counts in your results.

3. Install the SDK and bind push

Add the tranthor-push module next to tranthor-sdk. Your app adds com.google.firebase:firebase-messaging itself and keeps its own Firebase configuration (google-services.json or manual FirebaseOptions). The app never holds the server key.
The Android SDK artifacts are not on Maven yet. Contact us at support@tranthor.com for the build to add to your project.
Bind push to the SDK once, in Application.onCreate, after the SDK is configured:
Keep push for the life of the app. Forward every FCM token to it: the token from FirebaseMessaging.getInstance().token at launch and every onNewToken callback. The simplest way is the ready-made messaging service, which forwards tokens, shows each Tranthor push and reports that it arrived:
images lets the notification show the template’s image. The app downloads it only when the image URL starts with https:// and its host is exactly one of the hosts you list there, and by default only a JPG, PNG or GIF up to 5 MB. Otherwise the notification shows without the image. In the push editor, the Image card takes the image. Upload saves a JPG, PNG or GIF up to 5 MB to your workspace’s assets and uses it; a WebP or a bigger file is refused, here and when you upload in Choose from assets. Choose from assets picks one you already have. Both come from your workspace’s asset storage, so add that host to the list too. To read the host, open ··· › Paste a link on the card: the field shows the image’s full link. Paste a link also takes any other image link, with variables. A link without variables that does not start with https:// is refused and not saved. A link with variables is refused the same way when it starts with a scheme other than https://, such as http:// or ftp://; otherwise, as when it starts with a variable, it is checked by what it fills in as for the preview customer. The AI chat refuses the same links. Messages that are not from Tranthor go to onOtherMessage, so another push SDK keeps working. To report opens, call TranthorNotifications.interactionFrom(context, intent) in your activity’s onCreate and onNewIntent and pass the result to push.handle(...). To report dismissals, do the same in the dismiss receiver. On Android 13 and later, posting notifications needs the POST_NOTIFICATIONS permission. The SDK never asks for it on its own; ask at a moment that suits your app, then call push.refreshPermission(). Identity and consent follow the SDK: identify, reset, optOut and optIn on TranthorSDK keep the phone’s registration in step.

Events the SDK sends

The SDK sends these as track events through its queue, under the customer’s user id (or anonymous id when there is none). Tranthor reserves these names. Each phone of a customer is an Installation. A customer can have several.

What Tranthor sends to the phone

Tranthor sends data-only FCM messages, with no notification block, so your app always builds the notification itself and can report what happens to it:
  • tranthor is a JSON string. It holds version (always 1), the deliveryId the SDK reports back, the imageUrl when the template has one, and "test": true for a test push.
  • title, body, channelId (the template’s Channel id, under Advanced) and url (the template’s When tapped, open link) are left out when empty.
  • The template’s data entries are added as their own keys. A data key named tranthor, title, body, channelId, url, from or message_type, or starting with google. or gcm., is not sent.
  • Title, body, image URL, the When tapped, open link and data values can use Liquid, like other templates.
  • FCM limits a message’s data to 4096 bytes. A longer message is not sent, and the send fails with a reason.
  • FCM keeps an undelivered message for up to 28 days.

Which phones receive a push

Tranthor never sends a push only to find out whether a phone is still there. A phone stays reachable until there is real evidence that it is not:
  • Removed at once: when Google says the token is no longer registered, when the app sends Installation Removed, or when the phone has not registered for 90 days. The SDK registers on every app start, so a phone in use never reaches 90 days.
  • Paused after two rejections: when Google rejects a phone’s token twice in a row. A paused phone comes back when the app gets a new token from Firebase.
  • Notification permission: a phone the SDK reports as "denied" is skipped. "unknown" still receives push.
Each message goes to at most 10 of a customer’s phones, the most recently seen first. A customer with no reachable phone is skipped, not failed. If Google is unavailable and no phone accepted a message, Tranthor tries again, up to 5 attempts in all over about 50 minutes, then records the message as failed. If Google refuses your key, Tranthor stops push to that app, marks the key Unhealthy on Settings, Mobile, Push, and shows it in Needs you. No phone is removed because of a bad key. While the key is Unhealthy, send a test push from the Settings page or a push template’s editor: if Google accepts it, the key is Healthy again and push resumes. Otherwise replace the key on the Settings page.

Results

Push results show on each journey step, on the journey’s Stats tab and on a broadcast’s results:
  • Sent: Google accepted the message for at least one of the customer’s phones.
  • Delivered: the app on the phone reported Push Received. This is app-reported: a phone that was off, or an app that did not run its messaging service, reports nothing, so Delivered can be lower than what reached phones.
  • Opened: the customer tapped the notification (Push Opened).
  • Failed: no phone accepted the message. The Stats tab and a broadcast’s results list failures by reason, in words.
  • Not sent: a customer with no phone that can get push from the app is skipped, shown as No active Installation under Push not sent. A skip is neither sent nor failed.
Each message counts once, however many phones it reached. Dismissals are stored but not shown as a result. The SDK’s reports count only when their deliveryId matches a push Tranthor sent to that same customer. Anything else is ignored. Test pushes never count.

Troubleshooting

Firebase says “Key creation is not allowed on this service account”

Your Google Cloud organization blocks new service-account keys. It does this with the organization policy iam.disableServiceAccountKeyCreation. Google turns this policy on by default for organizations created after mid-2024. You can turn it off for your Firebase project only. The rest of your organization keeps it.
  1. Make sure you have the Organization Policy Administrator role. If you do not, ask your Google Cloud admin.
  2. In the Google Cloud console, go to IAM & Admin, then Organization Policies.
  3. In the project picker at the top, select your Firebase project. Do not select the organization.
  4. Open Disable service account key creation. There are two entries with this name, a legacy one and a managed one. Open the one that shows Active.
  5. Select Manage policy, then Override parent’s policy.
  6. Add a rule and set Enforcement to Off. Then select Set policy.
  7. Wait up to 15 minutes for the change to take effect.
  8. In Firebase, select Generate new private key again.

Current limits

  • Android only. iOS (APNs) is not available yet. The editor already lets you prepare iOS: under Settings › Message, Different for each gives the iOS version its own title, subtitle, body and image, and Advanced holds the iOS Sound and Time sensitive options. These are saved with the template and shown in the iOS preview, but nothing is sent to iPhones, and Android phones get the same push as before.
  • Turned on per workspace. Ask us to turn it on for yours.
  • The Android SDK artifacts are not on Maven yet.
  • Push is sent by people in the dashboard. In the push template editor, the AI chat can write and change the template’s draft. It writes the shared (Android) message only, and does not see or edit the iOS version. It cannot publish the template, start a journey or send push.
  • The Supervisor and connected assistants such as Claude and ChatGPT can read push templates, journeys and results, but cannot create, start or send push yet.
  • Reachable audience and Blast radius counts do not include push yet.