How to keep sending push to your OneSignal subscribers through your own Firebase
By Factodus · updated
Since 1 October 2026 the free OneSignal plan pauses mobile push once an organization goes over 1,000 monthly active users. If your Android app already uses the OneSignal SDK, you don’t have to ship an update to keep reaching the people who installed it: the push tokens it registered belong to your Firebase project, and Firebase Cloud Messaging (FCM) will deliver to them no matter who sends the request.
Short version. Export your subscribers with the OneSignal REST API (allowed on the free plan): the
identifiercolumn is the FCM token. Get an OAuth token from your Firebase service account and POST each message tofcm.googleapis.com/v1/projects/<project-id>/messages:send. We tested this end to end on an Android 16 phone with OneSignal Android SDK 5.1.
Check that the tokens are yours
This only works if OneSignal registered the devices under your Firebase project, which is the normal setup: you uploaded your Firebase service account JSON to OneSignal (Settings → Push & In-App → Google Android (FCM)).
To confirm, compare two numbers:
- your Firebase project number: Firebase console → Project settings → General;
- the
android_sender_idOneSignal hands to the SDK:https://api.onesignal.com/apps/<your-app-id>/android_params.js, or look for it inadb logcatwith OneSignal’s log level set to verbose.
If they match, every token in your list is an FCM token of your project.
1. Export the subscribers
Create a REST API key in OneSignal (Settings → Keys & IDs → Add key) and request a CSV export:
curl -s -X POST "https://api.onesignal.com/players/csv_export?app_id=$APP_ID" \
-H "Authorization: Key $ONESIGNAL_REST_KEY" \
-H "Content-Type: application/json" -d '{}'
The answer contains csv_file_url. The file is built in the background, so poll that URL until it returns 200. It is
a gzipped CSV; the columns that matter here:
| Column | Meaning |
|---|---|
identifier |
the push token; for Android, the FCM registration token |
device_type |
1 is Android, 0 is iOS |
tags |
your OneSignal tags, as JSON, handy for segments |
last_active |
when the user last opened the app |
invalid_identifier |
t if OneSignal already knows the token is dead, otherwise f |
Keep the Android rows with a non-empty identifier and invalid_identifier = f.
2. Get an access token for FCM
Use the same service account JSON you gave OneSignal. In Python with google-auth:
from google.auth.transport.requests import Request
from google.oauth2 import service_account
creds = service_account.Credentials.from_service_account_file(
"service-account.json", scopes=["https://www.googleapis.com/auth/firebase.messaging"])
creds.refresh(Request())
print(creds.token) # valid for about an hour
3. Send
FCM v1 takes one token per request:
curl -s -X POST "https://fcm.googleapis.com/v1/projects/$PROJECT_ID/messages:send" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{"message": {"token": "'"$FCM_TOKEN"'",
"notification": {"title": "Hello", "body": "Sent straight through FCM"}}}'
A 200 with a message name means FCM accepted it. Loop over your list with modest concurrency.
Things to know
- Use
notificationmessages. When the app is in the background, Android shows them by itself, without any app code. That is the case we tested. While the app is open, the message goes to the OneSignal SDK in the app, which may not display a payload it didn’t send. - Clean up dead tokens. A
404withUNREGISTEREDmeans the app was uninstalled or the token rotated; drop it. - New installs keep coming. The SDK in your app still registers new devices with OneSignal, so repeat the export now and then and merge the new tokens.
- The Firebase console can’t do this for you. Its campaigns only reach devices registered by the Firebase SDK of an app you added to the project, not tokens the OneSignal SDK created. We sent a campaign to our test app and it never arrived.
- iOS tokens in the export are APNs device tokens. They need your APNs
.p8key and Apple’s HTTP/2 API instead of FCM. We haven’t tested that path yet. - Web push and email stay free on OneSignal, so you can keep using it for those.