A fully-featured iOS/Android push notification sample application for testing integration with Treasure Data Engage Studio.
This sample app implements the following features:
- ✅ FCM token acquisition and registration
- ✅ Push notification reception and display
- ✅ Rich media notifications (image display)
- ✅ Deep link support
- ✅ Web link support (Safari/Chrome Custom Tabs)
- ✅ Event tracking (delivery, open, dismiss, link_open, deeplink_open, link_arrive, link_fail, token_register)
- ✅ Automatic upload to Treasure Data Ingest API
- ✅ Offline-ready event queue
- ✅ Secure link handling (domain/host allowlist)
- iOS: 13.0 and above
- Android: 8.0 and above (API 26)
- Create a project in Firebase Console
- Register iOS app (Bundle ID:
com.treasuredata.pushsample) - Register Android app (Package name:
com.treasuredata.pushsample) - Download
GoogleService-Info.plist(iOS) andgoogle-services.json(Android)
iOS APNs Setup:
- Create APNs authentication key (.p8 file) in Apple Developer Portal
- Firebase Console > Project Settings > Cloud Messaging > Upload APNs authentication key
- Log in to Treasure Data Console
- Create database and table (e.g.,
mobile.push_events) - Obtain Write-only API key (Settings > API Keys)
Tools required for iOS development:
- Xcode 15.0+ (Full version)
- Install from App Store
⚠️ Command Line Tools alone are insufficient (iOS Simulator unavailable)- After installation, run:
sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer xcode-select -p # Verify output is /Applications/Xcode.app/Contents/Developer
- XcodeGen (Project file generation tool)
brew install xcodegen
# 0. Generate Xcode project (first time only)
cd ios
xcodegen generate
cd ..
# 1. Place Firebase configuration file
cp ios/TDPushSample/GoogleService-Info.plist.example ios/TDPushSample/GoogleService-Info.plist
# Edit GoogleService-Info.plist with your actual Firebase configuration
# 2. Edit Info.plist with your Treasure Data configuration
# - TDWriteKey: YOUR_TD_WRITE_KEY
# - TDDatabase: mobile
# - TDTable: push_events
# - TDEndpoint: https://us01.records.in.treasuredata.com
# 3. Open project in Xcode
open ios/TDPushSample.xcodeprojXcode Configuration:
- Signing & Capabilities > Select Team
- If changing Bundle Identifier, update URL Scheme in Info.plist as well
- Enable Capabilities > Push Notifications
- Enable Capabilities > Background Modes > Remote notifications
- Swift Package Manager will automatically download dependencies on first build
- Firebase Messaging (12.7.0+)
- Firebase Analytics (12.7.0+)
- Treasure Data iOS SDK (1.2.1+)
Note:
- This project uses Swift Package Manager (SPM)
- CocoaPods is not used (open
.xcodeproj, not.xcworkspace) - Dependencies are managed in
project.ymland generated via XcodeGen
# 1. Place Firebase configuration file
cp android/app/google-services.json.example android/app/google-services.json
# Edit google-services.json with your actual Firebase configuration
# 2. Configure Treasure Data API Key (build-time injection)
cd android
cp local.properties.example local.properties
# Edit local.properties and set TD_WRITE_KEY and other values
# Example:
# TD_WRITE_KEY=your_api_key
# TD_DATABASE=mobile
# TD_TABLE=push_events
# TD_ENDPOINT=https://us01.records.in.treasuredata.com
# 3. Build and install
./gradlew assembleDebug
./gradlew installDebugNote: local.properties is not committed to Git (for security)
iOS:
# Check in Xcode console
# "🔑 FCM token: xxxxx" will be displayedAndroid:
adb logcat | grep "FCM token"
# "🔑 FCM token: xxxxx" will be displayed- Firebase Console > Cloud Messaging > New Campaign > Notifications
- Enter notification text
- Test message > Enter FCM token > Test
iOS Simulator:
# Launch simulator
open -a Simulator
xcrun simctl boot "iPhone 15"
# Send test notification
xcrun simctl push booted com.treasuredata.pushsample shared/test-payloads/test-notification.apnsAndroid:
# Use Firebase Admin SDK or curl (requires Server Key)
# See docs/TESTING.md for detailsCheck events in Treasure Data Console to verify they are being tracked correctly.
All events include the following fields:
| Field | Type | Description |
|---|---|---|
type |
string | Event type (delivery, open, dismiss, link_open, deeplink_open, link_arrive, link_fail, token_register) |
campaign_id |
string | Campaign ID |
platform |
string | Platform (ios/android) |
fcm_token |
string | FCM token |
user_id |
string | User ID (optional) |
value |
string | Link or deep link URL (only for link_open/deeplink_open/link_arrive/link_fail) |
reason |
string | Failure reason (only for link_fail: invalid_link, domain_not_allowed, unknown_path, browser_open_failed) |
time |
string | ISO8601 timestamp (UTC) |
Default scheme: tdpushsample://
Supported Routes:
tdpushsample://product/{id}- Product detailtdpushsample://category/{id}- Categorytdpushsample://home- Home
Configuration:
- Android: Change
DEEP_LINK_SCHEMEinapp/build.gradle.kts - iOS: Change
TDDeepLinkSchemeandCFBundleURLSchemesinInfo.plist
HTTPS URLs are opened in browser:
- Android: Chrome Custom Tabs
- iOS: Safari
Security:
- Validated against domain allowlist (
ALLOWED_DOMAINS/TDAllowedDomains) - Disallowed domains trigger
link_failevent tracking
For details, see docs/LINK_IMPLEMENTATION_SUMMARY.md
See docs/TROUBLESHOOTING.md for details.
iOS: Notifications not arriving
- Verify APNs authentication key is registered in Firebase Console
- Ensure device is physical (simulator does not support APNs)
- Check Background Modes > Remote notifications is enabled
Android: Notifications not arriving
- Verify google-services.json is correctly placed
- Ensure Package name matches com.treasuredata.pushsample
- Check internet permission is granted
Events not sent to Treasure Data
- Verify TD_WRITE_KEY is correctly configured
- Check network connection
- Check HTTP status code in app logs (200 = success)
Links not working
- Verify domain/host is in allowlist
- Check
reasonfield inlink_failevent to identify cause - See troubleshooting section in docs/LINK_IMPLEMENTATION_SUMMARY.md
.
├── android/ # Android app
│ ├── app/src/main/
│ │ ├── java/.../fcm/ # FCM-related services
│ │ └── res/ # Resources
│ └── build.gradle.kts
├── ios/ # iOS app
│ ├── TDPushSample/
│ │ ├── Models/ # Service classes
│ │ ├── AppDelegate.swift
│ │ ├── SceneDelegate.swift
│ │ └── TrackingService.swift
│ ├── NotificationService/ # Notification extension
│ └── Podfile
├── shared/
│ └── test-payloads/ # Test payloads
├── docs/ # Documentation
│ ├── LINK_IMPLEMENTATION_SUMMARY.md
│ ├── LINK_IMPLEMENTATION_SUMMARY_ja.md
│ ├── SETUP.md
│ ├── TESTING.md
│ └── TROUBLESHOOTING.md
├── README.md # English README (this file)
└── README_ja.md # Japanese README
- Treasure Data Mobile Push Documentation
- Firebase Cloud Messaging
- Apple Push Notification Service
- Treasure Data Ingest API
This sample code is provided under the MIT License.
If you encounter any issues, please contact Treasure Data support.