1{"version":3,"file":"updateDevicePushTokenAsync.js","sourceRoot":"","sources":["../../src/utils/updateDevicePushTokenAsync.ts"],"names":[],"mappings":"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","sourcesContent":["import { computeNextBackoffInterval } from '@ide/backoff';\nimport * as Application from 'expo-application';\nimport { CodedError, Platform, UnavailabilityError } from 'expo-modules-core';\n\nimport ServerRegistrationModule from '../ServerRegistrationModule';\nimport { DevicePushToken } from '../Tokens.types';\n\nconst updateDevicePushTokenUrl = 'https://exp.host/--/api/v2/push/updateDeviceToken';\n\nexport async function updateDevicePushTokenAsync(signal: AbortSignal, token: DevicePushToken) {\n  const doUpdateDevicePushTokenAsync = async (retry: () => void) => {\n    const [development, deviceId] = await Promise.all([\n      shouldUseDevelopmentNotificationService(),\n      getDeviceIdAsync(),\n    ]);\n    const body = {\n      deviceId: deviceId.toLowerCase(),\n      development,\n      deviceToken: token.data,\n      appId: Application.applicationId,\n      type: getTypeOfToken(token),\n    };\n\n    try {\n      const response = await fetch(updateDevicePushTokenUrl, {\n        method: 'POST',\n        headers: {\n          'content-type': 'application/json',\n        },\n        body: JSON.stringify(body),\n        signal,\n      });\n\n      // Help debug erroring servers\n      if (!response.ok) {\n        console.debug(\n          '[expo-notifications] Error encountered while updating the device push token with the server:',\n          await response.text()\n        );\n      }\n\n      // Retry if request failed\n      if (!response.ok) {\n        retry();\n      }\n    } catch (e) {\n      // Error returned if the request is aborted should be an 'AbortError'. In\n      // React Native fetch is polyfilled using `whatwg-fetch` which:\n      // - creates `AbortError`s like this\n      //   https://github.com/github/fetch/blob/75d9455d380f365701151f3ac85c5bda4bbbde76/fetch.js#L505\n      // - which creates exceptions like\n      //   https://github.com/github/fetch/blob/75d9455d380f365701151f3ac85c5bda4bbbde76/fetch.js#L490-L494\n      if (e.name === 'AbortError') {\n        // We don't consider AbortError a failure, it's a sign somewhere else the\n        // request is expected to succeed and we don't need this one, so let's\n        // just return.\n        return;\n      }\n\n      console.warn(\n        '[expo-notifications] Error thrown while updating the device push token with the server:',\n        e\n      );\n\n      retry();\n    }\n  };\n\n  let shouldTry = true;\n  const retry = () => {\n    shouldTry = true;\n  };\n\n  let retriesCount = 0;\n  const initialBackoff = 500; // 0.5 s\n  const backoffOptions = {\n    maxBackoff: 2 * 60 * 1000, // 2 minutes\n  };\n  let nextBackoffInterval = computeNextBackoffInterval(\n    initialBackoff,\n    retriesCount,\n    backoffOptions\n  );\n\n  while (shouldTry && !signal.aborted) {\n    // Will be set to true by `retry` if it's called\n    shouldTry = false;\n    await doUpdateDevicePushTokenAsync(retry);\n\n    // Do not wait if we won't retry\n    if (shouldTry && !signal.aborted) {\n      nextBackoffInterval = computeNextBackoffInterval(\n        initialBackoff,\n        retriesCount,\n        backoffOptions\n      );\n      retriesCount += 1;\n      await new Promise((resolve) => setTimeout(resolve, nextBackoffInterval));\n    }\n  }\n}\n\n// Same as in getExpoPushTokenAsync\nasync function getDeviceIdAsync() {\n  try {\n    if (!ServerRegistrationModule.getInstallationIdAsync) {\n      throw new UnavailabilityError('ExpoServerRegistrationModule', 'getInstallationIdAsync');\n    }\n\n    return await ServerRegistrationModule.getInstallationIdAsync();\n  } catch (e) {\n    throw new CodedError(\n      'ERR_NOTIFICATIONS_DEVICE_ID',\n      `Could not fetch the installation ID of the application: ${e}.`\n    );\n  }\n}\n\n// Same as in getExpoPushTokenAsync\nfunction getTypeOfToken(devicePushToken: DevicePushToken) {\n  switch (devicePushToken.type) {\n    case 'ios':\n      return 'apns';\n    case 'android':\n      return 'fcm';\n    // This probably will error on server, but let's make this function future-safe.\n    default:\n      return devicePushToken.type;\n  }\n}\n\n// Same as in getExpoPushTokenAsync\nasync function shouldUseDevelopmentNotificationService() {\n  if (Platform.OS === 'ios') {\n    try {\n      const notificationServiceEnvironment =\n        await Application.getIosPushNotificationServiceEnvironmentAsync();\n      if (notificationServiceEnvironment === 'development') {\n        return true;\n      }\n    } catch (e) {\n      // We can't do anything here, we'll fallback to false then.\n    }\n  }\n\n  return false;\n}\n"]}