1import { UnavailabilityError, Platform } from 'expo-modules-core';
2
3import PushTokenManager from './PushTokenManager';
4import { DevicePushToken } from './Tokens.types';
5
6let nativeTokenPromise: Promise<string> | null = null;
7
8/**
9 * Returns a native FCM, APNs token or a [`PushSubscription` data](https://developer.mozilla.org/en-US/docs/Web/API/PushSubscription)
10 * that can be used with another push notification service.
11 * @header fetch
12 */
13export default async function getDevicePushTokenAsync(): Promise<DevicePushToken> {
14  if (!PushTokenManager.getDevicePushTokenAsync) {
15    throw new UnavailabilityError('ExpoNotifications', 'getDevicePushTokenAsync');
16  }
17
18  let devicePushToken: string | null;
19  if (nativeTokenPromise) {
20    // Reuse existing Promise
21    devicePushToken = await nativeTokenPromise;
22  } else {
23    // Create a new Promise and clear it afterwards
24    nativeTokenPromise = PushTokenManager.getDevicePushTokenAsync();
25    devicePushToken = await nativeTokenPromise;
26    nativeTokenPromise = null;
27  }
28
29  // @ts-ignore: TS thinks Platform.OS could be anything and can't decide what type is it
30  return { type: Platform.OS, data: devicePushToken };
31}
32