Push Notifications in Kivy
Learn how to integrate push notifications in Kivy with this practical mobile app development tutorial. Understand the core concepts, dive into hands-on steps, explore real-world options, and troubleshoot edge cases. Perfect for developers progressing through the Mobile App Development track.
Focus: integrate push notifications in kivy
You’ve built a beautiful Kivy app, but it only talks to the user when it’s open. The moment they swipe it away, your app goes silent — no order confirmations, no chat replies, no breaking news. Without push notifications, your users are left guessing, and your engagement metrics flatline. In this lesson, you’ll learn how to integrate push notifications in Kivy, turning your passive app into a proactive partner that reaches users even when the screen is off.
The problem this lesson solves
Push notifications are the difference between an app users check and an app that checks in with them. But here’s the uncomfortable truth: Kivy doesn’t have a built-in push notification API — and mobile push systems (FCM on Android, APNs on iOS) are deeply platform-specific. If you try to glue a generic Python library into your Kivy app, you’ll hit a wall of background-service limits, missing device tokens, and notifications that simply don’t fire when the app is closed.
This lesson cuts through the confusion. You’ll learn the core concepts, a practical integration path, and the common traps that break push delivery — so your Kivy app can send and receive notifications reliably on both Android and iOS.
Core concept / mental model
Think of push notifications as a postal system, not a direct phone call. Your app doesn’t keep a line open to a server. Instead, three parties cooperate:
- Your backend (or a third-party service) — the sender who writes the message.
- A push gateway (FCM or APNs) — the postal service that routes the message to the correct device.
- Your Kivy app — the recipient that registers its address (called a device token) and displays the incoming mail.
Every device gets a unique token when your app first registers with the gateway. Your backend stores that token and later sends a message addressed to it. The gateway holds the message until the device is online, then delivers it — even if your app is killed or in the background.
Key mental model: Push notifications are server-to-device messages. The platform (Android/iOS) handles the delivery; your Kivy app just needs to register, listen, and display.
Because Kivy itself is platform-agnostic, you’ll bridge into native code using a helper library — most commonly plyer for simple local notifications or kivy-remote-notifications for full FCM/APNs support. The choice depends on whether you need local alerts (timers, reminders) or remote push from your own server.
How it works step by step
Here’s the end-to-end flow, from setup to delivery:
- Set up a Firebase project (for Android) or Apple Developer account (for iOS) and enable push messaging. For Android, you’ll need the
google-services.jsonfile placed in your app’splatforms/androiddirectory. - Install the bridge library — e.g.,
plyerfor local notifications, orkivy-remote-notificationsfor remote push. - Register for a device token — the library contacts FCM/APNs and returns a token string.
- Send the token to your backend — via a simple HTTP POST so your server knows where to deliver messages.
- Handle incoming messages — in your Kivy app, you define a callback that runs when a notification arrives. This callback often updates the UI or triggers a local notification.
- Send a push from your backend — using the Firebase Admin SDK or the FCM REST API, targeting the stored token.
Each step has a cause-and-effect relationship: if you skip token registration, the backend has no address; if you skip the background-service setup, your app won’t wake up to receive the message.
Hands-on walkthrough
Prerequisites
Make sure you have:
- Python 3.10+ and a virtual environment
- A Kivy app structure (a
main.pyfile at minimum) - For Android: Firebase project +
google-services.json - For iOS: Apple Developer membership and APNs certificate
Local notifications with plyer (simplest start)
If you just need to fire a notification from within your app (e.g., a reminder), use plyer. It wraps the native notification API and works in Kivy with zero external services.
from kivy.app import App
from kivy.uix.button import Button
from plyer import notification
class PushApp(App):
def notify_me(self, instance):
notification.notify(
title='Hello from Kivy!',
message='This is a local push notification.',
app_name='MyKivyApp',
timeout=5
)
def build(self):
btn = Button(text='Notify me')
btn.bind(on_press=self.notify_me)
return btn
PushApp().run()
Expected output: When you tap the button, a system notification appears with the title and message you set. This works both in a desktop window and on a mobile device after packaging.
Pro tip:
plyeris perfect for local notifications, but it cannot receive remote pushes. For that, you need the next example.
Remote push with kivy-remote-notifications
This library handles FCM on Android and APNs on iOS, and exposes a clean Python API.
First, install it:
pip install kivy-remote-notifications
Then integrate into your main.py:
from kivy.app import App
from kivy.clock import Clock
from kivy.uix.label import Label
from kivy_remote_notifications import KivyRemoteNotifications
class PushApp(App):
def build(self):
self.notifier = KivyRemoteNotifications()
self.notifier.register_remote_notifications()
self.notifier.set_callback(self.on_notification)
return Label(text='Waiting for push…')
def on_notification(self, message):
# Runs when the app is foregrounded and a push arrives
self.root.text = f'Got: {message}'
def on_start(self):
Clock.schedule_once(lambda dt: self.send_token_to_backend(), 5)
def send_token_to_backend(self):
token = self.notifier.get_token()
# TODO: POST token to your server
print(f'Device token: {token}')
PushApp().run()
What you’ll see: After a few seconds, the console prints a long token string. That token is the address your backend will use. When you send a test push from the Firebase console, the label updates — if the app is in the foreground.
Pro tip: On Android, if the app is killed, the system still shows the notification, but your Python code won’t run. Plan a fallback UI update when the user taps the notification and reopens the app.
Sending a push from your backend (Firebase Admin)
Assuming you have a server-side Python script, use Firebase Admin SDK to target your device token.
from firebase_admin import credentials, messaging, initialize_app
cred = credentials.Certificate('service-account.json')
initialize_app(cred)
message = messaging.Message(
notification=messaging.Notification(
title='Order update',
body='Your coffee is ready!'
),
token='YOUR_DEVICE_TOKEN_HERE'
)
response = messaging.send(message)
print('Sent:', response)
Expected output: The script prints Sent: projects/your-project/messages/1234567890. The device with that token receives the notification, and if your Kivy app is in the foreground, the callback fires.
Compare options / when to choose what
Not every push solution fits every app. Here’s a quick comparison:
| Solution | Best for | Platform | Effort | Needs backend? |
|---|---|---|---|---|
plyer local notifications |
Timers, reminders, alerts | Android + iOS + desktop | Low | No |
| FCM (Firebase Cloud Messaging) | Remote push from your server | Android (iOS via APNs) | Medium | Yes |
| APNs (Apple Push Notification service) | Native iOS apps | iOS only | High | Yes |
| Third-party services (OneSignal, Pusher) | Fast setup, analytics | Cross-platform | Low–Med | Partial |
Choose plyer when you don’t need server-triggered messages. Choose FCM if you have your own backend and target both Android and iOS. If you want a managed dashboard and segmentation, a third-party service may save time — but you code against their API, not directly against FCM.
Troubleshooting & edge cases
No token generated
- Cause: Google services missing or wrong Firebase config.
- Fix: Double-check
google-services.jsonis insideplatforms/android(if using Buildozer). Also verify the package name matches the one in Firebase.
Notifications don’t appear when app is in background
- Cause: Kivy doesn’t run in the background on Android; the system handles the notification, but your Python callback never executes.
- Fix: Use a native service or a plugin that writes the payload to a file. On next app start, read that file and display the notification content.
Token changes between app restarts
- Cause: OS can rotate tokens for security.
- Fix: Implement a
token refreshcallback (if the library supports it) and re-send the new token to your backend.
Push works on Android but not iOS
- Cause: APNs requires a valid
.p8certificate and proper provisioning profile. - Fix: Enable Push Notifications capability in Xcode, and upload your APNs auth key to your push service (or Firebase).
Notification appears twice
- Cause: Both a local notification (via
plyer) and a remote notification are fired for the same event. - Fix: Avoid handling remote pushes by creating a local notification. Only use one notification path.
What you learned & what's next
You now understand the postal system behind push notifications, you can integrate push notifications in Kivy using plyer or kivy-remote-notifications, you know how to send your device token to your backend, and you’ve seen how to handle incoming messages with callbacks. You also know the key differences between local and remote notifications, and you can troubleshoot the most common failure points.
Key takeaway: Push delivery is handled by the platform, not Kivy. Your job is to register, listen, and display — and to keep your token fresh.
Next in the Mobile App Development track, you’ll learn how to store data locally with SQLite or Room, so your notifications can link to deeper app content. With push + local storage, your app becomes both proactive and persistent — a winning combination.
Practice recap
Create a simple Kivy app that uses plyer to fire a local notification when a button is pressed. Then, install kivy-remote-notifications, register for a token, and print it — don’t worry about the backend yet. Finally, simulate a remote push using FCM’s console to verify the callback updates your UI when the app is open.
Common mistakes
- Using
plyerfor remote push — it only handles local notifications, so FCM/APNs messages will never arrive. - Forgetting to add
google-services.jsonto your Android build — FCM registration silently fails and you get no token. - Assuming Python code runs when the app is killed on Android — the notification shows, but your callback doesn’t execute; plan a fallback on app restart.
- Hardcoding a device token in your backend — tokens rotate, so implement refresh logic to avoid permanent delivery failures.
- Generating both a local and remote notification for the same event, which results in duplicate alerts.
Variations
- Use
plyerfor local notifications only, avoiding any external services. - Use Firebase Cloud Messaging (FCM) with the
kivy-remote-notificationslibrary for full remote push on Android and iOS. - Use a third-party service like OneSignal or Pusher to handle token management and segmentation with minimal backend code.
Real-world use cases
- An e-commerce Kivy app sends order status updates and delivery tracking alerts to customers via FCM.
- A task-management app uses local notifications to remind users of upcoming deadlines without needing a backend.
- A social chat app uses
kivy-remote-notificationsto wake the UI and display new message banners while the app is foregrounded.
Key takeaways
- Push notifications are server-to-device messages; the platform gateway handles delivery, not Kivy itself.
- Register your app with FCM/APNs to obtain a device token, then send that token to your backend.
- Use
plyerfor local notifications andkivy-remote-notifications(or similar) for remote push. - Handle token refresh to maintain reliable delivery as OS rotates tokens.
- When the app is killed on Android, Python callbacks don’t run — read a stored payload on next launch instead.
- Choose the right solution: local vs. remote vs. third-party service based on your backend and feature needs.
Keep learning
Related tutorials, quizzes, and articles for this topic.
Discussion
Questions, corrections, and tips help everyone reading this page.
0 comments
Add a comment
No comments yet — start the thread.