Geliştiriciler · API v1.0.0
React Native (Bare / CLI) Entegrasyonu
Bu rehber npx @react-native-community/cli init ile oluşturulmuş (Expo olmayan) React Native projeleri içindir. Genel API referansı için Genel bakış dosyasına bakın.
Desteklenen sürümler: React Native 0.74+ (New Architecture dahil) · iOS 13.4+ · Android 7.0+ (API 24) · Node 18+
NotiPilot 1.0.0 teslimatı Expo Push Service üzerinden yaptığı için cihazın bir Expo Push Token'ına ihtiyacı vardır. Bare React Native projesinde bunun iki yolu vardır:
| Yöntem | Ne zaman? |
|---|---|
A. expo-notifications (önerilen) |
Çoğu proje için. Expo modülleri bare projeye eklenir; Expo'ya geçiş gerektirmez. |
B. @react-native-firebase/messaging + token dönüşümü |
Projede zaten Firebase Messaging kullanılıyorsa. |
Her iki yöntemde de bir EAS projesi oluşturmanız (npx eas-cli init) ve FCM V1 / APNs kimlik bilgilerini eas credentials ile yüklemeniz gerekir. EAS proje ID'si, NotiPilot panelindeki Expo Project ID alanına girilen ve API'ye app_id olarak gönderilen değerdir.
Yöntem A — expo-notifications (önerilen)
1. Kurulum
npx install-expo-modules@latest
npx expo install expo-notifications expo-device expo-secure-store expo-localization expo-crypto expo-application
cd ios && pod install && cd ..
Android
- Firebase konsolundan
google-services.jsondosyasını indiripandroid/app/içine koyun. android/build.gradle→dependencies { classpath 'com.google.gms:google-services:4.4.2' }android/app/build.gradle→ en altaapply plugin: 'com.google.gms.google-services'
iOS (Xcode → Signing & Capabilities)
- Push Notifications capability'sini ekleyin.
- Background Modes → Remote notifications seçeneğini işaretleyin.
2. İstemci kodu
Expo rehberindeki src/notipilot.ts dosyasını aynen kullanabilirsiniz. Bare projede expo-constants manifest'i bulunmadığı için yalnızca proje ID'sini sabit olarak verin ve app_version değerini expo-application'dan alın:
import * as Application from 'expo-application';
// NotiPilot panelindeki "Expo Project ID" ile aynı
const PROJECT_ID = 'EAS-PROJE-ID-NIZ';
// registerDevice() içindeki attributes:
// app_version: Application.nativeApplicationVersion,
Yöntem B — Firebase Messaging + Expo token dönüşümü
Projede @react-native-firebase/messaging zaten kuruluysa, cihazın native token'ını Expo token'ına dönüştürüp NotiPilot'a gönderebilirsiniz.
npm i @react-native-firebase/app @react-native-firebase/messaging react-native-get-random-values uuid @react-native-async-storage/async-storage react-native-localize react-native-device-info
import 'react-native-get-random-values';
import { v4 as uuidv4 } from 'uuid';
import messaging from '@react-native-firebase/messaging';
import AsyncStorage from '@react-native-async-storage/async-storage';
import * as RNLocalize from 'react-native-localize';
import DeviceInfo from 'react-native-device-info';
import { Platform, PermissionsAndroid } from 'react-native';
const NOTIPILOT_BASE_URL = 'https://app.notipilot.com/api/v1';
const PROJECT_ID = 'EAS-PROJE-ID-NIZ';
async function getDeviceUid() {
let uid = await AsyncStorage.getItem('notipilot_device_uid');
if (!uid) {
uid = uuidv4();
await AsyncStorage.setItem('notipilot_device_uid', uid);
}
return uid;
}
async function requestPermission(): Promise<boolean> {
if (Platform.OS === 'android' && Platform.Version >= 33) {
const r = await PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.POST_NOTIFICATIONS);
if (r !== PermissionsAndroid.RESULTS.GRANTED) return false;
}
const status = await messaging().requestPermission();
return (
status === messaging.AuthorizationStatus.AUTHORIZED ||
status === messaging.AuthorizationStatus.PROVISIONAL
);
}
/** Native FCM/APNs token'ını Expo Push Token'a dönüştürür. */
async function toExpoPushToken(deviceUid: string): Promise<string> {
const isIOS = Platform.OS === 'ios';
const deviceToken = isIOS ? await messaging().getAPNSToken() : await messaging().getToken();
if (!deviceToken) throw new Error('Native push token alınamadı');
const res = await fetch('https://exp.host/--/api/v2/push/getExpoPushToken', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
type: isIOS ? 'apns' : 'fcm',
deviceId: deviceUid.toLowerCase(),
development: __DEV__ && isIOS, // iOS debug build'leri APNs sandbox kullanır
appId: DeviceInfo.getBundleId(), // Android package / iOS bundle id
deviceToken,
projectId: PROJECT_ID,
}),
});
if (!res.ok) throw new Error(`Expo token dönüşümü başarısız: ${res.status}`);
const json = await res.json();
return json.data.expoPushToken; // "ExponentPushToken[...]"
}
export async function registerDevice(extra: Record<string, string | number | boolean | null> = {}) {
if (!(await requestPermission())) return null;
const deviceUid = await getDeviceUid();
const token = await toExpoPushToken(deviceUid);
const locale = RNLocalize.getLocales()[0];
const res = await fetch(`${NOTIPILOT_BASE_URL}/register-device`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
app_id: PROJECT_ID,
device_uid: deviceUid,
token,
platform: Platform.OS,
provider: 'expo',
attributes: {
locale: locale?.languageCode ?? null,
country: RNLocalize.getCountry(),
app_version: DeviceInfo.getVersion(),
...extra,
},
}),
});
return res.json();
}
// Token yenilendiğinde tekrar kaydedin
messaging().onTokenRefresh(() => registerDevice().catch(() => {}));
exp.host/--/api/v2/push/getExpoPushToken, Expo'nun kendiexpo-notificationskütüphanesinin kullandığı endpoint'tir; Expo tarafından ayrıca dokümante edilmemiştir. Uzun vadeli en güvenli seçenek Yöntem A'dır.
identify-device çağrısı ve hata yönetimi için Expo rehberindeki identify, logout ve post fonksiyonlarını aynen kullanabilirsiniz.
Kontrol listesi
- EAS projesi oluşturuldu, proje ID'si panelde Expo Project ID olarak girildi
-
eas credentialsile FCM V1 + APNs kimlik bilgileri yüklendi - Android 13+ için
POST_NOTIFICATIONSizni isteniyor - iOS'ta Push Notifications + Remote notifications capability'leri açık
-
countryve mümkünsecityattributes olarak gönderiliyor