Entwickler · API v1.0.0
React-Native-Integration (Bare / CLI)
Dieser Leitfaden richtet sich an React-Native-Projekte (ohne Expo), die mit npx @react-native-community/cli init erstellt wurden. Die allgemeine API-Referenz finden Sie in der Überblick.
Unterstützte Versionen: React Native 0.74+ (inkl. New Architecture) · iOS 13.4+ · Android 7.0+ (API 24) · Node 18+
Da NotiPilot 1.0.0 über den Expo Push Service zustellt, benötigt das Gerät einen Expo Push Token. In einem Bare-React-Native-Projekt gibt es dafür zwei Wege:
| Methode | Wann? |
|---|---|
A. expo-notifications (empfohlen) |
Für die meisten Projekte. Expo-Module werden dem Bare-Projekt hinzugefügt; ein Umstieg auf Expo ist nicht nötig. |
B. @react-native-firebase/messaging + Token-Konvertierung |
Wenn das Projekt bereits Firebase Messaging nutzt. |
Bei beiden Methoden müssen Sie ein EAS-Projekt anlegen (npx eas-cli init) und die FCM-V1- / APNs-Zugangsdaten mit eas credentials hochladen. Die EAS-Projekt-ID ist der Wert, der im NotiPilot-Dashboard im Feld Expo Project ID eingetragen und als app_id an die API gesendet wird.
Methode A — expo-notifications (empfohlen)
1. Installation
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
- Laden Sie die Datei
google-services.jsonaus der Firebase-Konsole herunter und legen Sie sie inandroid/app/ab. android/build.gradle→dependencies { classpath 'com.google.gms:google-services:4.4.2' }android/app/build.gradle→ ganz untenapply plugin: 'com.google.gms.google-services'
iOS (Xcode → Signing & Capabilities)
- Fügen Sie die Capability Push Notifications hinzu.
- Aktivieren Sie unter Background Modes die Option Remote notifications.
2. Client-Code
Sie können die Datei src/notipilot.ts aus dem Expo-Leitfaden unverändert übernehmen. Da es in einem Bare-Projekt kein expo-constants-Manifest gibt, geben Sie lediglich die Projekt-ID als Konstante an und beziehen app_version aus expo-application:
import * as Application from 'expo-application';
// Identisch mit der "Expo Project ID" im NotiPilot-Dashboard
const PROJECT_ID = 'IHRE-EAS-PROJEKT-ID';
// Attributes in registerDevice():
// app_version: Application.nativeApplicationVersion,
Methode B — Firebase Messaging + Expo-Token-Konvertierung
Ist @react-native-firebase/messaging im Projekt bereits installiert, können Sie den nativen Token des Geräts in einen Expo-Token konvertieren und an NotiPilot senden.
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 = 'IHRE-EAS-PROJEKT-ID';
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
);
}
/** Konvertiert den nativen FCM-/APNs-Token in einen Expo Push Token. */
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('Nativer Push-Token konnte nicht abgerufen werden');
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-Builds nutzen die APNs-Sandbox
appId: DeviceInfo.getBundleId(), // Android package / iOS bundle id
deviceToken,
projectId: PROJECT_ID,
}),
});
if (!res.ok) throw new Error(`Expo-Token-Konvertierung fehlgeschlagen: ${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();
}
// Bei Token-Erneuerung erneut registrieren
messaging().onTokenRefresh(() => registerDevice().catch(() => {}));
exp.host/--/api/v2/push/getExpoPushTokenist der Endpoint, den Expos eigene Bibliothekexpo-notificationsverwendet; er ist von Expo nicht gesondert dokumentiert. Langfristig ist Methode A die sicherste Option.
Für den Aufruf von identify-device und die Fehlerbehandlung können Sie die Funktionen identify, logout und post aus dem Expo-Leitfaden unverändert übernehmen.
Checkliste
- EAS-Projekt angelegt, Projekt-ID im Dashboard als Expo Project ID eingetragen
- FCM-V1- + APNs-Zugangsdaten mit
eas credentialshochgeladen - Unter Android 13+ wird die Berechtigung
POST_NOTIFICATIONSangefragt - Unter iOS sind die Capabilities Push Notifications + Remote notifications aktiviert
-
countryund nach Möglichkeitcitywerden als Attributes gesendet