Ana içeriğe geç

React Native SDK

@opennotification/react-native iOS ve Android'i tek JavaScript API'sinden kapsar ve native tarafın tamamı paketin içinde gelir: @react-native-firebase/* yok, Notifee yok, AsyncStorage yok. iOS native bir modülle doğrudan APNs'e konuşur — Firebase iOS SDK'sı yok. Android, Kotlin SDK'yı Firebase Messaging üzerinde gömülü çalıştırır ve her bildirimi kendisi çizer; Firebase Messaging npm'den değil Gradle'dan gelir.

1 Kur

bun add @opennotification/react-native

Sonra birini seçin: Expo plugin ya da elle kurulum.

2 Başlat

import { OpenNotification } from "@opennotification/react-native";

await OpenNotification.init({
endpoint: "https://push.example.com",
appKey: "pk_live_…",
autoRegister: false, // true: init sırasında izin iste
androidSmallIcon: "ic_notification", // drawable adı, tek renkli
});

init native dinleyicileri bağlar ve Android'de FCM token'ını alıp hemen kaydeder (token almak için izin gerekmez). iOS'ta izin verilene kadar hiçbir şey gönderilmez. index.js'e kaydedilecek bir arka plan handler'ı yok: çizim ve takip native olduğu için FCM'in süreci içinde JavaScript olmadan uyandırması sorun değil.

3 İzin, kimlik, tag'ler, açılmalar

const result = await OpenNotification.requestPermission();
if (!result.ok) console.warn(result.error.code); // permission_denied | no_token | api_error | network_error

await OpenNotification.login("user_123");
await OpenNotification.setTags({ plan: "platinum", streak: 42 });

const off = OpenNotification.onOpen((message) => {
navigate(message.data.screen ?? "Home", message.data); // message.url, message.actionId de var
});
OpenNotification.onReceive((message) => {
if (message.silent) sync(message.data); // arka plan push'u: bir şey gösterilmedi, mesaj data'dır
});

await OpenNotification.logout();
await OpenNotification.unsubscribe();
await OpenNotification.trackSession(); // isteğe bağlı; AppState "active" bunu kendiliğinden yapar

onOpen soğuk açılışta da tetiklenir: native taraf basışı JavaScript hazır olana kadar tutar.

Oturumlar sizin için sayılır: start() AppState'i dinler ve her ön plana dönüşte /session'a ping atar; sunucu 30 dakika boşluk kuralını uygular, çift sayım olmaz. Sessiz push'lar onReceive'e message.silent === true ile gelir — iOS'ta application(_:didReceiveRemoteNotification:fetchCompletionHandler:)OpenNotification.didReceiveBackground(userInfo:)'ya iletin (aşağıdaki AppDelegate) ve Remote notifications background mode'unu açın.

await OpenNotification.permissionStatus() granted | denied | provisional | not_determined döner; OpenNotification.register() kaydı açıkça yeniden gönderir.

removeTags / setLanguage için alttaki istemciyi kullanın: const client = await OpenNotification.init(…); client.removeTags(["streak"]).

Expo config plugin

{
"expo": {
"ios": { "bundleIdentifier": "com.acme.app" },
"android": { "googleServicesFile": "./google-services.json" },
"plugins": [
["@opennotification/react-native", {
"endpoint": "https://push.example.com",
"androidSmallIconPath": "./assets/ic_notification.png"
}]
]
}
}

npx expo prebuild (ya da EAS build) aşağıdaki elle kurulumun listelediği her şeyi uygular:

PlatformPlugin ne yapar
iOSaps-environment entitlement'ı, remote-notification arka plan modu, dört AppDelegate callback'i, Info.plist'inde OpenNotificationApiUrl = endpoint olan bir NotificationService extension hedefi.
AndroidPOST_NOTIFICATIONS izni, androidSmallIconPath'i res/drawable/ic_notification.png'ye kopyalar. google-services.json ve Gradle eklentisi Expo'nun kendi android.googleServicesFile'ından gelir.
SeçenekVarsayılan
endpointExtension için API taban URL'si.
iosServiceExtensiontrueExtension'ı atlamak için false (o zaman iOS'ta delivered yok).
iosServiceExtensionNameNotificationServiceHedef adı; bundle id <bundleIdentifier>.<ad>.
iosDeploymentTargetuygulamanınki
iosApsEnvironmentdevelopmentEAS build sırasında doğrusunu koyar.
androidSmallIconPathTek renkli PNG, saydam üzerine beyaz.
androidSmallIconic_notificationYukarıdaki PNG'nin drawable adı.

Sizde kalanlar: extension'ın App ID'si ve profili (com.acme.app.NotificationService) — ya da extra.eas.build.experimental.ios.appExtensions ile EAS'a bırakın — ve .p8 yüklemesi (iOS platform kurulumu). Plugin Expo SDK 53+'ın Swift AppDelegate'ini yamalar ve aynı bildirim delegate'ini sahiplenen expo-notifications ile birlikte çalışmaz.

Elle kurulum (bare React Native)

Android

1 android/app/ içinde google-services.json ve Gradle eklentisi — Android platform kurulumu. Firebase Messaging paketin Gradle modülüyle gelir; dependencies'e bir şey eklemeyin.

2 android/app/src/main/res/drawable/ic_notification.png konumunda tek renkli durum çubuğu simgesi (saydam üzerine beyaz), androidSmallIcon olarak verilir. Android başka her şeyi gri kare çizer.

3 Android 13+: requestPermission() POST_NOTIFICATIONS ister; izni modülün manifest'i bildirir.

Autolinking modülü bir sonraki build'de alır. Zaten bir FirebaseMessagingService'iniz var mı? onNewToken ve onMessageReceived'i Kotlin SDK'nın anlattığı gibi iletin — aynı kod.

iOS

1 cd ios && pod install.

2 Xcode → uygulama hedefi → Signing & CapabilitiesPush Notifications ve Background Modes → Remote notifications ekleyin.

3 AppDelegate'ten dört callback'i iletin. Swift:

import OpenNotification
import UserNotifications

// application(_:didFinishLaunchingWithOptions:) içinde
UNUserNotificationCenter.current().delegate = self
OpenNotification.setLaunchNotification(launchOptions?[.remoteNotification] as? [AnyHashable: Any])

func application(_ application: UIApplication,
didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
OpenNotification.didRegister(deviceToken: deviceToken)
}
func application(_ application: UIApplication,
didFailToRegisterForRemoteNotificationsWithError error: Error) {
OpenNotification.didFailToRegister(error: error)
}

extension AppDelegate: UNUserNotificationCenterDelegate {
func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: @escaping () -> Void) {
OpenNotification.didReceive(response: response)
completionHandler()
}
func userNotificationCenter(_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
OpenNotification.willPresent(notification: notification)
completionHandler([.banner, .sound, .badge])
}
}

Objective-C AppDelegate.mm: #import "YourApp-Swift.h" ve aynı dört OpenNotification sınıf metodunu çağırın.

Bunlar olmadan izin verilir, token hiç gelmez ve requestPermission() no_token ile döner.

4 Notification Service Extension — iOS'ta delivered, görsel ve buton için zorunlu:

  1. File → New → Target… → Notification Service Extension, adı NotificationService, deployment target = uygulamanınki.
  2. NotificationService.swift'ini node_modules/@opennotification/react-native/ios/NotificationServiceExtension/NotificationService.swift ile değiştirin.
  3. Extension'ın Info.plist'ine String OpenNotificationApiUrl = API taban URL'niz ekleyin.
  4. Kendi App ID / profilini verin (com.acme.app.NotificationService).

5 .p8'i yükleyin — iOS platform kurulumu.

Ne neyi bildirir

OlayiOSAndroid
deliveredNotification Service ExtensionFirebaseMessagingService (native)
openeddidReceive response → native modülNotificationReceiver (native)
clicked (buton)action identifier'lı didReceivebuton id'li NotificationReceiver
dismissediOS'ta yokNotificationReceiver (native)

Android'de her ping native gönderilir — FCM süreci içinde JavaScript olmadan uyandırabilir — JavaScript istemcisi olayları yalnızca dinleyicilerinize iletir. iOS'ta açılmaları istemci kendisi bildirir.

Notlar

  • Mesajlar normalize edilir: APNs on bloğu ve FCM düz data, ikisi de tek OpenNotificationMessage olarak gelir.
  • @opennotification/core'dan yalnızca tipler içe aktarılır — sunucudan hiçbir şey bundle'ınıza girmez.
  • Abonelik kimliği UserDefaults / SharedPreferences'ta durur. Uygulama kalıcılığı kendi yönetmek isterse createClient'a kendi storage'ınızı verin; hiç native modül yokken (testler) bellekte kalır ve cihaz bir sonraki açılışta yeniden kaydolur, bu da aynı satırı token'a göre upsert eder.