Skip to content

Instantly share code, notes, and snippets.

@stigi
Created January 22, 2025 22:36
Show Gist options
  • Save stigi/4e0296d7c5e8ac92dffb0c7b9f6e14cb to your computer and use it in GitHub Desktop.
Save stigi/4e0296d7c5e8ac92dffb0c7b9f6e14cb to your computer and use it in GitHub Desktop.
MagicBell device token handling with user tracking
import { DevicePushToken, getDevicePushTokenAsync } from "expo-notifications";
import { useState, useEffect } from "react";
import { Platform } from "react-native";
import * as RNPushInfo from "react-native-push-info";
import * as mb from "@magicbell/react-headless";
const tokenPath = Platform.select({
ios: "/channels/mobile_push/apns/tokens",
android: "/channels/mobile_push/fcm/tokens",
})!;
const apnsTokenPayload = (token: string) => ({
apns: {
device_token: token,
installation_id: RNPushInfo.getIOSAPNSEnvironment(),
app_id: RNPushInfo.getIOSBundleId(),
},
});
const fcmTokenPayload = (token: string) => ({
fcm: {
device_token: token,
},
});
export function useDeviceToken() {
const [token, setToken] = useState<DevicePushToken | null>(null);
const clientSettings = mb.clientSettings.getState();
const userKey = clientSettings.userEmail || clientSettings.userExternalId;
const [userKeyUsedToRegister, setUserKeyUsedToRegister] = useState<
string | null
>(null);
useEffect(() => {
getDevicePushTokenAsync().then((deviceToken) => setToken(deviceToken));
}, []);
useEffect(() => {
// No token, nothing to register/unregister
if (!token) {
return;
}
const userChanged = userKey !== userKeyUsedToRegister;
// If the credentials didn't change, we don't need to register/unregister
if (!userChanged) {
return;
}
// The token was previously registered and needs to be unregistered after the login changed
// (i.e. when logging in as a different user, or logging out)
if (userKeyUsedToRegister) {
mb.deleteAPI(tokenPath + "/" + token);
setUserKeyUsedToRegister(null);
}
// We're logged in (after a logout, or after logging in as a new user) and need to register the token
if (userKey) {
const data =
token.type === "ios"
? apnsTokenPayload(token.data)
: fcmTokenPayload(token.data);
mb.postAPI(tokenPath, data).then();
setUserKeyUsedToRegister(userKey);
}
}, [token, userKey, userKeyUsedToRegister]);
return token;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment