<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/the-react-native-live-activities-handbook-how-to-build-ios-live-activities-and-android-16-live-upda-zpnvakxef" -->

---
title: The React Native Live Activities Handbook: How to Build...
description: A comprehensive guide to implementing iOS Live Activities and Android 16 Live Updates in React Native using a custom Expo native module. Covers the fundamental...
canonical: https://daily.dev/posts/the-react-native-live-activities-handbook-how-to-build-ios-live-activities-and-android-16-live-upda-zpnvakxef
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: The React Native Live Activities Handbook: How to Build iOS Live Activities and Android 16 Live Updates | daily.dev
og:description: A comprehensive guide to implementing iOS Live Activities and Android 16 Live Updates in React Native using a custom Expo native module. Covers the fundamental...
og:url: https://daily.dev/posts/the-react-native-live-activities-handbook-how-to-build-ios-live-activities-and-android-16-live-upda-zpnvakxef
og:image: https://api.daily.dev/og/posts/ZPnVAkXEf.png
og:image:alt: The React Native Live Activities Handbook: How to Build iOS Live Activities and Android 16 Live Updates
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# The React Native Live Activities Handbook: How to Build iOS Live Activities and Android 16 Live Updates

**[freeCodeCamp](https://daily.dev/sources/freecodecamp)** · 67 min read · 1 upvotes · 0 comments

## Summary

A comprehensive guide to implementing iOS Live Activities and Android 16 Live Updates in React Native using a custom Expo native module. Covers the fundamental architectural differences between the two platforms: iOS uses APNs to update a system-owned SwiftUI widget while the app is dead, whereas Android uses FCM to wake a background service that re-posts the notification manually. The guide walks through building a delivery-tracking demo called DropTrack, including the ActivityKit contract design (static vs. dynamic state split), SwiftUI widget implementation with a segmented progress bar and Dynamic Island layouts, bridging ActivityKit to JavaScript via Expo's Record API, writing an APNs client from scratch in ~60 lines of Node.js, and handling silent failure modes like the identical-copy trap, the eta epoch mismatch, and activity state loss on cold start.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://www.freecodecamp.org/news/react-native-live-activities-handbook>

## Questions this post answers

### Why does my APNs push to a Live Activity return 200 but the card never updates?

APNs only validates that it accepted the bytes, not that the widget could decode them. If the content-state JSON field names or types don't exactly match the Codable ContentState struct in the widget, iOS silently discards the update with zero logged error. A common cause is sending etaEpochMillis (Unix milliseconds, used by the native bridge) instead of eta as seconds since 2001, the format the widget's Codable struct expects.

_Anyone shipping ActivityKit push updates can find this exact eta-format gotcha explained on daily.dev._

### Why does canPostPromotedNotifications() return false on a Samsung device even after granting promotion permissions?

Samsung's One UI can grant the FLAG_PROMOTED_ONGOING request and satisfy every notification permission check, yet still withhold the chip pill, lock-screen card, and Now Bar entry because those surfaces are limited to a hardcoded six-app allowlist (Audio broadcast, Emergency sharing, Google Finance, Maps, Media player, and Sports from Google). Third-party apps only get top-of-shade pinning and a status-bar icon, confirmed across a Galaxy S26 Ultra and Galaxy A37 on One UI 8.5.

_Developers debugging Android promoted notifications on Samsung hardware can track findings like this on daily.dev._

### Why does androidx.core need to be at least version 1.17.0 to use Android 16 ProgressStyle promotion APIs?

Version 1.17.0 of androidx.core backports the Android 16 QPR1 (API 36.1) promotion methods, such as setRequestPromotedOngoing and setShortCriticalText, so they compile against base SDK 36. Without this dependency, those methods and the POST_PROMOTED_NOTIFICATIONS permission are not on the classpath, and calling the platform classes directly fails the build with a 'no such method' error.

_Teams targeting Android 16's promoted notifications can keep dependency requirements like this straight via daily.dev._

## Similar posts on daily.dev

- [Live Activities with Expo, End to End: Client and Backend — Expo blog](https://daily.dev/posts/live-activities-with-expo-end-to-end-client-and-backend-expo-blog-jwfjdu3w2) · Expo Blog · 0 upvotes · 0 comments
- [Let’s talk Live activities\!](https://daily.dev/posts/let-s-talk-live-activities--vsyx4n03l) · Medium · 0 upvotes · 0 comments
- [How to build a resilient activity tracker with Expo — Expo blog](https://daily.dev/posts/how-to-build-a-resilient-activity-tracker-with-expo-expo-blog-tscdigjcl) · Expo Blog · 2 upvotes · 0 comments
- [Making React Native actually native](https://daily.dev/posts/making-react-native-actually-native-bdan1xdzt) · Bytes by ui.dev · 2 upvotes · 0 comments

---

Tags: [#swift](https://daily.dev/tags/swift), [#react-native](https://daily.dev/tags/react-native)

[View this post on daily.dev](https://daily.dev/posts/the-react-native-live-activities-handbook-how-to-build-ios-live-activities-and-android-16-live-upda-zpnvakxef)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"The React Native Live Activities Handbook: How to Build iOS Live Activities and Android 16 Live Updates","url":"https://daily.dev/posts/the-react-native-live-activities-handbook-how-to-build-ios-live-activities-and-android-16-live-upda-zpnvakxef","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/the-react-native-live-activities-handbook-how-to-build-ios-live-activities-and-android-16-live-upda-zpnvakxef"},"datePublished":"2026-07-14T18:35:42.986Z","dateModified":"2026-09-13T19:39:46.062Z","description":"A comprehensive guide to implementing iOS Live Activities and Android 16 Live Updates in React Native using a custom Expo native module. Covers the fundamental...","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/bb2c0f536216bf2b462727918a6cee89?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/bb2c0f536216bf2b462727918a6cee89?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"freeCodeCamp","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"freeCodeCamp","logo":"https://media.daily.dev/image/upload/t_logo,f_auto/v1628412854/logos/freecodecamp","url":"https://daily.dev/sources/freecodecamp"},"commentCount":0,"discussionUrl":"https://daily.dev/posts/the-react-native-live-activities-handbook-how-to-build-ios-live-activities-and-android-16-live-upda-zpnvakxef","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":1},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"keywords":"swift,react-native","timeRequired":"PT67M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"freeCodeCamp","item":"https://daily.dev/sources/freecodecamp"},{"@type":"ListItem","position":3,"name":"The React Native Live Activities Handbook: How to Build iOS Live Activities and Android 16 Live Updates"}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/the-react-native-live-activities-handbook-how-to-build-ios-live-activities-and-android-16-live-upda-zpnvakxef#faq","mainEntity":[{"@type":"Question","name":"Why does my APNs push to a Live Activity return 200 but the card never updates?","acceptedAnswer":{"@type":"Answer","text":"APNs only validates that it accepted the bytes, not that the widget could decode them. If the content-state JSON field names or types don't exactly match the Codable ContentState struct in the widget, iOS silently discards the update with zero logged error. A common cause is sending etaEpochMillis (Unix milliseconds, used by the native bridge) instead of eta as seconds since 2001, the format the widget's Codable struct expects. Anyone shipping ActivityKit push updates can find this exact eta-format gotcha explained on daily.dev."}},{"@type":"Question","name":"Why does canPostPromotedNotifications() return false on a Samsung device even after granting promotion permissions?","acceptedAnswer":{"@type":"Answer","text":"Samsung's One UI can grant the FLAG_PROMOTED_ONGOING request and satisfy every notification permission check, yet still withhold the chip pill, lock-screen card, and Now Bar entry because those surfaces are limited to a hardcoded six-app allowlist (Audio broadcast, Emergency sharing, Google Finance, Maps, Media player, and Sports from Google). Third-party apps only get top-of-shade pinning and a status-bar icon, confirmed across a Galaxy S26 Ultra and Galaxy A37 on One UI 8.5. Developers debugging Android promoted notifications on Samsung hardware can track findings like this on daily.dev."}},{"@type":"Question","name":"Why does androidx.core need to be at least version 1.17.0 to use Android 16 ProgressStyle promotion APIs?","acceptedAnswer":{"@type":"Answer","text":"Version 1.17.0 of androidx.core backports the Android 16 QPR1 (API 36.1) promotion methods, such as setRequestPromotedOngoing and setShortCriticalText, so they compile against base SDK 36. Without this dependency, those methods and the POST_PROMOTED_NOTIFICATIONS permission are not on the classpath, and calling the platform classes directly fails the build with a 'no such method' error. Teams targeting Android 16's promoted notifications can keep dependency requirements like this straight via daily.dev."}}]}
```

