Skip to content

Commit 4fcd06f

Browse files
shanerbaner82claude
andcommitted
Add push notification deep link and data message support
- Handle FCM data payload deep links (url/link keys) in handleDeepLinkIntent for cold-start push notification navigation on Android - Add didReceiveRemoteNotification to AppDelegate for iOS data-only message delivery (silent push via content-available) - Fix IOSPluginCompiler to handle boolean values in nativephp.json info_plist entries (needed for FirebaseAppDelegateProxyEnabled: false) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 1476dfd commit 4fcd06f

3 files changed

Lines changed: 43 additions & 1 deletion

File tree

resources/androidstudio/app/src/main/java/com/nativephp/mobile/ui/MainActivity.kt

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,7 @@ class MainActivity : FragmentActivity(), WebViewProvider {
306306
}
307307

308308
private fun handleDeepLinkIntent(intent: Intent?) {
309-
// Check for notification URL extra (from local notification taps)
309+
// Check for notification URL extra (from local notification taps or foreground push)
310310
val notificationUrl = intent?.getStringExtra("notification_url")
311311
if (!notificationUrl.isNullOrEmpty()) {
312312
Log.d("DeepLink", "🔔 Notification URL: $notificationUrl")
@@ -320,6 +320,30 @@ class MainActivity : FragmentActivity(), WebViewProvider {
320320
return
321321
}
322322

323+
// Check for deep link URL from FCM data payload (background/killed push notifications)
324+
val fcmUrl = intent?.getStringExtra("url") ?: intent?.getStringExtra("link")
325+
if (!fcmUrl.isNullOrEmpty()) {
326+
Log.d("DeepLink", "🔔 FCM deep link URL: $fcmUrl")
327+
val uri = android.net.Uri.parse(fcmUrl)
328+
val scheme = uri.scheme
329+
val route = if (scheme != null && scheme != "http" && scheme != "https") {
330+
val host = uri.host ?: ""
331+
val path = uri.path ?: ""
332+
val query = uri.query?.let { "?$it" } ?: ""
333+
if (host.isNotEmpty()) "/$host$path$query" else "$path$query"
334+
} else {
335+
fcmUrl
336+
}
337+
pendingDeepLink = route
338+
if (::laravelEnv.isInitialized && ::webViewManager.isInitialized) {
339+
val fullUrl = "http://127.0.0.1$route"
340+
Log.d("DeepLink", "🚀 Loading FCM deep link immediately: $fullUrl")
341+
webView.loadUrl(fullUrl)
342+
pendingDeepLink = null
343+
}
344+
return
345+
}
346+
323347
val uri = intent?.data ?: return
324348
Log.d("DeepLink", "🌐 Received deep link: $uri")
325349

resources/xcode/NativePHP/AppDelegate.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,4 +107,18 @@ class AppDelegate: NSObject, UIApplicationDelegate {
107107
DeepLinkRouter.shared.handle(url: url)
108108
return true
109109
}
110+
111+
// Handle remote notifications (data-only messages, silent push)
112+
func application(
113+
_ application: UIApplication,
114+
didReceiveRemoteNotification userInfo: [AnyHashable: Any],
115+
fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void
116+
) {
117+
NotificationCenter.default.post(
118+
name: .didReceiveRemoteNotification,
119+
object: nil,
120+
userInfo: ["payload": userInfo]
121+
)
122+
completionHandler(.newData)
123+
}
110124
}

src/Plugins/Compilers/IOSPluginCompiler.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,10 @@ protected function injectPlistEntries(string $plist, array $entries): string
367367
$arrayContent .= "\n\t\t<string>{$item}</string>";
368368
}
369369
$entry = "\n\t<key>{$key}</key>\n\t<array>{$arrayContent}\n\t</array>";
370+
} elseif (is_bool($value)) {
371+
// Handle boolean values
372+
$boolTag = $value ? '<true/>' : '<false/>';
373+
$entry = "\n\t<key>{$key}</key>\n\t{$boolTag}";
370374
} else {
371375
// Handle string values - substitute placeholders
372376
$value = $this->substituteEnvPlaceholders($value);

0 commit comments

Comments
 (0)