Skip to content
Iris Edge StudiosIndependent game studio

Iris Edge Studios/ Guides/Engineering

Engineering

Push that coaches instead of nags: streak tips with OneSignal

Pinteza is a daily word game, so much of its retention comes from the streak. This note covers how we split its notifications into two channels, the single job OneSignal does in the second one, and a Settings mistake that made the integration look broken for days.

Two channels

The phone schedules most of Pinteza's notifications by itself: the daily word, a warning when a streak is about to end, a win-back after 3, 7 and 14 days away, and a note when a Streak Shield covered a missed day. They depend on things only the device knows, such as whether you played today and how many shields you hold, so they stay on the phone and no third party sees them.

OneSignal sends one kind of message, streak tips: occasional notes on how the game works, such as what a shield does. It does not send the daily word, streak warnings or promotions, so a player never gets the same reminder from both systems.

Nothing starts before the player opts in

The OneSignal SDK does not start until the player turns tips on. Setting the consent flag first is not enough by itself, because the SDK fetches its remote settings inside start() before it checks consent. So the initialisation call itself waits.

Three actions turn tips on: the reminder card's "Turn on reminders" button followed by the system permission, the same row in Settings, or the Streak tips switch. Allowing notifications in the phone's own settings does not. Turning tips off opts the subscription out first and withdraws consent about a minute later, once the app has been in the foreground on a working connection, because OneSignal blocks the opt-out request itself once consent is gone. If the app is closed before then, the withdrawal finishes on the next launch.

OneSignal gets no external ID and no location. It gets four tags: the app language, the edition (Portugal or Brazil), the streak as a range such as "4-6" rather than a number or dates, and whether on-device reminders are on.

The welcome Journey

There is one Journey, and a player enters it when they subscribe. Nothing is sent on day zero. After twelve hours, a window from 12:00 to 13:00 in the player's time zone sends the first tip at lunch: how Streak Shields protect a streak. Two days later the Journey skips anyone idle for 48 hours, since the on-device win-back reaches them that week, and branches on the streak tag. Players with a streak hear that every solved word joins their collection. Players without one get "No streak? Your words still count".

Three delivery settings do the rest. A collapse ID makes the Day 3 tip replace an unread Day 1 tip instead of stacking on top of it. A six-hour time to live stops a lunchtime tip from arriving in the evening next to the local reminders. And every push uses the app's own "Streak tips" Android channel, so the phone's notification settings apply to it. Tapping a tip opens the daily lobby.

Pinteza has two Portuguese editions, but OneSignal has a single pt language, so the templates choose the text with Liquid on the edition tag:

{% if user.tags.variant == "br" %}Sua sequência pode ter guarda-costas{% else %}A tua série pode ter guarda-costas{% endif %}

What we got wrong

For several days the dashboard showed one subscriber, a test phone, and we assumed the integration was broken. It was not. Settings had two groups of switches that both looked like "notifications on". "Daily reminder" and "Streak at risk" control the on-device channel and never touch OneSignal. Only "Streak tips" does. We had turned on every reminder and left the one switch that mattered off.

We found it by installing the Play Store build on a phone, turning on the right switch, and watching the SDK start in the device log and a subscription ID appear in Settings. We also considered subscribing everyone whose notifications were already allowed, to fill the dashboard. We built that change and reverted it before it shipped, because it would have collected data from people who had not chosen anything. The fix we plan is in the labels: two groups with their own headings, so a player can tell a reminder from a tip.

Results so far

Pinteza launched on Google Play on 25 September 2026, so these numbers are small. Eight test pushes to a test phone were delivered with no failures, and four were opened. On 30 September five devices were subscribed and four players had entered the welcome Journey. Its first tip reached a phone running the Play Store build at 12:07 that day and was opened 18 seconds later, according to the device log. That shows the setup works end to end on a store build. It says nothing about retention yet, and we will not claim it does until we have the data.

Three smaller notes. In our account, Journey sends did not show up in the notification list of the OneSignal API, so we read them in the Journey analytics. A session-duration event of zero seconds, which happens when the app closes right after it starts, is rejected with a 400 and is harmless. And test on a release build as well as a development build, because the release build is the one players install.

If you are building the same thing

  • Keep on-device reminders and remote messages apart, one job each.
  • Delay the SDK initialisation until the player chooses, and set the consent flag as well.
  • Send tags as ranges, not raw values or dates.
  • Start with one Journey, few messages, a collapse ID and a short time to live.
  • Leave out players another system already reaches.

Pinteza is out now on Google Play. The Streak tips switch is in Settings, Notifications.


More guides