Engineering

Push Notifications

Architecture

Push Comes to Shove

One API to rule them all, and a €100 fee to let Apple play along.

Matti Lehtinen
Matti Lehtinen March 26, 2026

Implementing push notifications seems like a straightforward must-have for any mobile app nowadays, but, as we discovered, the reality is far from straightforward. Even for a task as simple as sending “Toilets at area 2 are closed” or alerting people that the last call has arrived, this poses a pretty significant technical and financial challenge.

One Message, Two Worlds

One of the main difficulties lies in the fact that iOS and Android have completely different approaches to receiving push notifications from your own backend:

  • iOS uses the Apple Push Notification service, or APNs for short.

  • Android uses Firebase Cloud Messaging, or FCM.

That’s why, to send out a single emergency broadcast or message, a developer traditionally has to manage two different protocols, two different sets of credentials, and two error-handling logics.

Our Choice: Expo Push Notifications

After weighing several possible paths, including building our own entire program to “split up” the messages and guide them on their respective tracks towards the right service, or using expensive SaaS platforms like OneSignal to handle everything for us, we chose to go down a different route: The Expo Push Notification Service. As we were already building the app in a React Native environment, using the Expo framework, the integration of the service would be fairly streamlined.

Why We Liked It

  • Unified API: Instead of dealing with separate iOS and Android protocols, we send requests to a single Expo endpoint.

  • Reduced Native Code: Expo handles the heavy lifting of retrieving device tokens, saving us from writing platform-specific native code.

  • Cost-Effective: The service is entirely free to use.

The Trade-offs

Unfortunately, no solution is perfect. By using Expo, we introduced a “Middleman Risk”. This means that if Expo’s servers were to go down, our push notifications don’t ship, even if our own backend is perfectly healthy. We also have to manage throttling limits of max 600 notifications per second, which could delay blasts to thousands of users simultaneously. Finally, we are also responsible for personally managing device tokens, meaning we need to keep our database up to date if users install or uninstall the Billie’s Craft Beer Fest app, in order to keep our list clean.

The “Hidden” Costs

While the Expo service was free, mobile development rarely is. The most significant “shove” money-wise was the mandatory entry fee to the Apple ecosystem. To get push notifications working on iOS devices, a premium Apple Developer Account is required, costing approximately €100 per year. Beyond the cost of deployment, there is also that of the configuration. Even with Expo, we must manage Apple APNs keys and ensure certificates remain valid to prevent service interruptions.

Because of these mandatory fees, during the course of this project, we focused the testing of our notifications only on Android devices, which only require you to set up a Firebase project, which is free and not at all hard to set up. However, since we have already implemented Expo’s unified API, the Apple side should be quick to set up once the developer account is active.

The Final Verdict

Ultimately, implementing push notifications was less about the “push” and more about the infrastructure behind the “shove”, but luckily, choosing Expo Push Notification Service allowed us to sidestep the headache of managing fragmented protocols for iOS and Android separately, without the skyrocketing costs associated with specialized SaaS platforms.

Although the €100 “Apple Tax” may have limited our initial testing to only Android, it hasn’t stopped us from preparing for all devices globally. We’ve built a solid foundation, the backend is ready, the unified API is integrated, and most importantly: it all functions perfectly. When the festival lights finally go up and that developer account is active, we’ll be ready to reach every attendee, no matter what color their chat bubbles are.