Auto

Search

Ctrl K
Home
Guides
Reference
Learn
Reference version

SDK 51 (latest)


SDK 51 (latest)
app.json / app.config.js
metro.config.js
Accelerometer
AppleAuthentication
Application
Asset
AsyncStorage
Audio
AuthSession
AV
BackgroundFetch
BarCodeScanner
Barometer
Battery
BlurView
Brightness
BuildProperties
Calendar
Camera (legacy)
Camera
captureRef
Cellular
Checkbox
Clipboard
Constants
Contacts
Crypto
DateTimePicker
DevClient
Device
DeviceMotion
DocumentPicker
FaceDetector
FileSystem
FlashList
Font
GestureHandler
GLView
Gyroscope
Haptics
Image
ImageManipulator
ImagePicker
IntentLauncher
KeepAwake
LightSensor
LinearGradient
Linking
LocalAuthentication
Localization
Location
Lottie
Magnetometer
MailComposer
Manifests
MapView
MaskedView
MediaLibrary
NavigationBar
NetInfo
Network
Notifications
Pedometer
Picker
Print
Reanimated
registerRootComponent
SafeAreaContext
ScreenCapture
ScreenOrientation
Screens
SecureStore
SegmentedControl
Sensors
Sharing
Skia
Slider
SMS
Speech
SplashScreen
SQLite (legacy)
SQLite
StatusBar
StoreReview
Stripe
Svg
Symbols
SystemUI
TaskManager
TrackingTransparency
Updates
URL
Video (expo-av)
VideoThumbnails
Video
ViewPager
WebBrowser
WebView
Expo Updates v1
Expo Structured Field Values
Expo CLI
create-expo-app
qr.expo.dev
Glossary of terms
Visit documentation
Archive
Expo Snack
Discord and Forums
Newsletter
Expo Notifications iconExpo Notifications


A library that provides an API to fetch push notification tokens and to present, schedule, receive and respond to notifications.



expo-notifications provides an API to fetch push notification tokens and to present, schedule, receive and respond to notifications.

Push notifications (remote notifications) functionality provided by expo-notifications will be unavailable in Expo Go from SDK 52. Instead, use a development build. Scheduled notifications (local notifications) will remain available in Expo Go.
Features
Schedule a one-off notification for a specific date or some time from now
Schedule a notification repeating in some time interval (or a calendar date match on iOS)
Get and set the application badge icon number
Fetch a native device push token, so you can send push notifications with FCM and APNs
Fetch an Expo push token, so you can send push notifications with Expo
Listen to incoming notifications in the foreground and background
Listen to interactions with notifications
Handle notifications when the app is in the foreground
Imperatively dismiss notifications from Notification Center/tray
Create, update, and delete Android notification channels
Set custom icon and color for notifications on Android
Installation

Copy

npx expo install expo-notifications
If you are installing this in an existing React Native app (bare workflow), start by installing expo in your project. Then, follow the additional instructions as mentioned by library's README under "Installation in bare React Native projects" section.

Usage
Check out the example Snack below to see Notifications in action, make sure to use a physical device to test it. Push notifications don't work on emulators/simulators.


Copy


Open in Snack


import { useState, useEffect, useRef } from 'react';
import { Text, View, Button, Platform } from 'react-native';
import * as Device from 'expo-device';
import * as Notifications from 'expo-notifications';
import Constants from 'expo-constants';

Notifications.setNotificationHandler({
  handleNotification: async () => ({
    shouldShowAlert: true,
    shouldPlaySound: false,
    shouldSetBadge: false,
  }),
});

export default function App() {
  const [expoPushToken, setExpoPushToken] = useState('');
  const [channels, setChannels] = useState<Notifications.NotificationChannel[]>([]);
  const [notification, setNotification] = useState<Notifications.Notification | undefined>(
    undefined
  );
  const notificationListener = useRef<Notifications.Subscription>();
  const responseListener = useRef<Notifications.Subscription>();

  useEffect(() => {
    registerForPushNotificationsAsync().then(token => token && setExpoPushToken(token));

    if (Platform.OS === 'android') {
      Notifications.getNotificationChannelsAsync().then(value => setChannels(value ?? []));
    }
    notificationListener.current = Notifications.addNotificationReceivedListener(notification => {
      setNotification(notification);
    });

    responseListener.current = Notifications.addNotificationResponseReceivedListener(response => {
      console.log(response);
    });

    return () => {
      notificationListener.current &&
        Notifications.removeNotificationSubscription(notificationListener.current);
      responseListener.current &&
        Notifications.removeNotificationSubscription(responseListener.current);
    };
  }, []);

  return (
    <View
      style={{
        flex: 1,
        alignItems: 'center',
        justifyContent: 'space-around',
      }}>
      <Text>Your expo push token: {expoPushToken}</Text>
      <Text>{`Channels: ${JSON.stringify(
        channels.map(c => c.id),
        null,
        2
      )}`}</Text>
      <View style={{ alignItems: 'center', justifyContent: 'center' }}>
        <Text>Title: {notification && notification.request.content.title} </Text>
        <Text>Body: {notification && notification.request.content.body}</Text>
        <Text>Data: {notification && JSON.stringify(notification.request.content.data)}</Text>
      </View>
      <Button
        title="Press to schedule a notification"
        onPress={async () => {
          await schedulePushNotification();
        }}
      />
    </View>
  );
}

async function schedulePushNotification() {
  await Notifications.scheduleNotificationAsync({
    content: {
      title: "You've got mail! 📬",
      body: 'Here is the notification body',
      data: { data: 'goes here', test: { test1: 'more data' } },
    },
    trigger: { seconds: 2 },
  });
}

async function registerForPushNotificationsAsync() {
  let token;

  if (Platform.OS === 'android') {
    await Notifications.setNotificationChannelAsync('default', {
      name: 'default',
      importance: Notifications.AndroidImportance.MAX,
      vibrationPattern: [0, 250, 250, 250],
      lightColor: '#FF231F7C',
    });
  }

  if (Device.isDevice) {
    const { status: existingStatus } = await Notifications.getPermissionsAsync();
    let finalStatus = existingStatus;
    if (existingStatus !== 'granted') {
      const { status } = await Notifications.requestPermissionsAsync();
      finalStatus = status;
    }
    if (finalStatus !== 'granted') {
      alert('Failed to get push token for push notification!');
      return;
    }
    // Learn more about projectId:
    // https://docs.expo.dev/push-notifications/push-notifications-setup/#configure-projectid
    // EAS projectId is used here.
    try {
      const projectId =
        Constants?.expoConfig?.extra?.eas?.projectId ?? Constants?.easConfig?.projectId;
      if (!projectId) {
        throw new Error('Project ID not found');
      }
      token = (
        await Notifications.getExpoPushTokenAsync({
          projectId,
        })
      ).data;
      console.log(token);
    } catch (e) {
      token = `${e}`;
    }
  } else {
    alert('Must use physical device for Push Notifications');
  }

  return token;
}
Present the notification to the user
import * as Notifications from 'expo-notifications';

// First, set the handler that will cause the notification
// to show the alert

Notifications.setNotificationHandler({
  handleNotification: async () => ({
    shouldShowAlert: true,
    shouldPlaySound: false,
    shouldSetBadge: false,
  }),
});

// Second, call the method

Notifications.scheduleNotificationAsync({
  content: {
    title: 'Look at that notification',
    body: "I'm so proud of myself!",
  },
  trigger: null,
});
Handle push notifications with navigation
If you'd like to deep link to a specific screen in your app when you receive a push notification, you can configure either of Expo's navigation systems to do that.

Expo RouterReact Navigation
You can use Expo Router's built-in deep linking to handle incoming URLs from push notifications. Simply configure the root layout to listen for incoming and initial notification events.


Copy


import { useEffect } from 'react';
import * as Notifications from 'expo-notifications';
import { router } from 'expo-router';

function useNotificationObserver() {
  useEffect(() => {
    let isMounted = true;

    function redirect(notification: Notifications.Notification) {
      const url = notification.request.content.data?.url;
      if (url) {
        router.push(url);
      }
    }

    Notifications.getLastNotificationResponseAsync()
      .then(response => {
        if (!isMounted || !response?.notification) {
          return;
        }
        redirect(response?.notification);
      });

    const subscription = Notifications.addNotificationResponseReceivedListener(response => {
      redirect(response.notification);
    });

    return () => {
      isMounted = false;
      subscription.remove();
    };
  }, []);
}

export default function Layout() {
  useNotificationObserver();

  return <Slot />;
}
Configuration
Credentials
Android
Firebase Cloud Messaging credentials are required for all Android apps to receive push notifications in your app (except when testing in Expo Go). For more information, see how to get FCM credentials for your app.

iOS
To register your iOS device and automatically enable push notifications for your EAS Build, see push notification setup.

App config
To configure expo-notifications, use the built-in config plugin in the app config (app.json or app.config.js) for EAS Build or with npx expo run:[android|ios]. The plugin allows you to configure the following properties that cannot be set at runtime and require building a new app binary to take effect:

Configurable properties
Name	Default	Description
icon	-	
Only for: 

Local path to an image to use as the icon for push notifications. 96x96 all-white png with transparency.

color	#ffffff	
Only for: 

Tint color for the push notification image when it appears in the notification tray.

defaultChannel	-	
Only for: 

Default channel for FCMv1 notifications.

sounds	-	
Array of local paths to sound files (.wav recommended) that can be used as custom notification sounds.

Here is an example of using the config plugin in the app config file:


Copy


{
  "expo": {
    "plugins": [
      [
        "expo-notifications",
        {
          "icon": "./local/assets/notification-icon.png",
          "color": "#ffffff",
          "defaultChannel": "default",
          "sounds": [
            "./local/assets/notification-sound.wav",
            "./local/assets/notification-sound-other.wav"
          ]
        }
      ]
    ]
  }
}
The iOS APNs entitlement is always set to 'development'. Xcode automatically changes this to 'production' during the archive. Learn more.

Permissions
Android
On Android, this module requires permission to subscribe to the device boot. It's used to setup scheduled notifications when the device (re)starts. The RECEIVE_BOOT_COMPLETED permission is added automatically through the library AndroidManifest.xml.

Starting from Android 12 (API level 31), to schedule the notification that triggers at the exact time, you need to add <uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM"/> to AndroidManifest.xml. You can read more about the exact alarm permission.

On Android 13, app users must opt-in to receive notifications via a permissions prompt automatically triggered by the operating system. This prompt will not appear until at least one notification channel is created. The setNotificationChannelAsync must be called before getDevicePushTokenAsync or getExpoPushTokenAsync to obtain a push token. You can read more about the new notification permission behavior for Android 13 in the official documentation.

Android Permission	Description
RECEIVE_BOOT_COMPLETED

Allows an application to receive the Intent.ACTION_BOOT_COMPLETED that is broadcast after the system finishes booting.

Allows an application to receive the Intent.ACTION_BOOT_COMPLETED that is broadcast after the system finishes booting. If you don't request this permission, you will not receive the broadcast at that time. Though holding this permission does not have any security implications, it can have a negative impact on the user experience by increasing the amount of time it takes the system to start and allowing applications to have themselves running without the user being aware of them. As such, you must explicitly declare your use of this facility to make that visible to the user.
SCHEDULE_EXACT_ALARM

Allows applications to use exact alarm APIs.

iOS
No usage description is required, see notification-related permissions.

Notification events listeners
Notification events include incoming notifications, interactions your users perform with notifications (this can be tapping on a notification, or interacting with it via notification categories), and rare occasions when your notifications may be dropped.

A few different listeners are exposed, so we've provided a chart below which will hopefully help you understand when you can expect each one to be triggered:

User interacted with notification?	App state	Listener(s) triggered
false	Foreground	NotificationReceivedListener
false	Foreground or Background	BackgroundNotificationTask
false	Killed	none
true	Foreground	NotificationReceivedListener & NotificationResponseReceivedListener
true	Background	NotificationResponseReceivedListener
true	Killed	useLastNotificationResponse or getLastNotificationResponseAsync
In the table above, whenever NotificationResponseReceivedListener is triggered, the same would apply to the useLastNotificationResponse hook.

When the app is not running or killed and is restarted by tapping on a notification, the NotificationResponseReceivedListener may or may not be triggered. To reliably capture the response, we recommend using useLastNotificationResponse or getLastNotificationResponseAsync.
Background notifications
Background event listeners are not supported in Expo Go.
A background notification (iOS) or a data-only notification (Android) is a remote notification that does not display an alert, play a sound, or add a badge to your app's icon. The purpose of a background notification is to provide a way to wake up your app to trigger an app data refresh in the background.

To handle notifications while the app is in the background or not running, you need to do the following:

Add expo-task-manager package to your project.
In your application code, set up a background task to run when the notification is received.
For Android:

Send a push notification payload containing only the data key.
For iOS:

In the array under the ios.infoPlist.UIBackgroundModes key in your app config, add the values remote-notification and processing.
Add _contentAvailable: true to your push notification payload for the Expo push notification service. Under normal circumstances, the "content-available" flag should launch your app in the background.
Additional information
Set custom notification sounds
Custom notification sounds are only supported when using EAS Build.

To add custom push notification sounds to your app, add the expo-notifications plugin to your app.json file and then under the sounds key, provide an array of local paths to sound files that can be used as custom notification sounds. These local paths are local to your project.


Copy


{
  "expo": {
    "plugins": [
      [
        "expo-notifications",
        {
          "sounds": ["local/path/to/mySoundFile.wav"]
        }
      ]
    ]
  }
}
After building your app, the array of files will be available for use in both NotificationContentInput and NotificationChannelInput. You only need to provide the base filename. Here's an example using the config above:

await Notifications.setNotificationChannelAsync('new-emails', {
  name: 'E-mail notifications',
  importance: Notifications.AndroidImportance.HIGH,
  sound: 'mySoundFile.wav', // Provide ONLY the base filename
});

await Notifications.scheduleNotificationAsync({
  content: {
    title: "You've got mail! 📬",
    sound: 'mySoundFile.wav', // Provide ONLY the base filename
  },
  trigger: {
    seconds: 2,
    channelId: 'new-emails',
  },
});
You can also manually add notification files to your Android and iOS projects if you prefer:

Android push notification payload specification
When sending a push notification, put an object conforming to the following type as data of the notification:

export interface FirebaseData {
  title?: string;
  message?: string;
  subtitle?: string;
  sound?: boolean | string;
  vibrate?: boolean | number[];
  priority?: AndroidNotificationPriority;
  badge?: number;
}
Interpret the iOS permissions response
On iOS, permissions for sending notifications are a little more granular than they are on Android. Because of this, you should rely on the NotificationPermissionsStatus's ios.status field, instead of the root status field. This value will be one of the following, accessible under Notifications.IosAuthorizationStatus:

NOT_DETERMINED: The user hasn't yet made a choice about whether the app is allowed to schedule notifications
DENIED: The app isn't authorized to schedule or receive notifications
AUTHORIZED: The app is authorized to schedule or receive notifications
PROVISIONAL: The application is provisionally authorized to post noninterruptive user notifications
EPHEMERAL: The app is authorized to schedule or receive notifications for a limited amount of time
Manage notification categories (interactive notifications)
Notification categories allow you to create interactive push notifications, so that a user can respond directly to the incoming notification either via buttons or a text response. A category defines the set of actions a user can take, and then those actions are applied to a notification by specifying the categoryIdentifier in the NotificationContent.

Image of notification categories on Android and iOS
On iOS, notification categories also allow you to customize your notifications further. With each category, not only can you set interactive actions a user can take, but you can also configure things like the placeholder text to display when the user disables notification previews for your app.

Platform specific guides
Handling notification channels 
Starting in Android 8.0 (API level 26), all notifications must be assigned to a channel. For each channel, you can set the visual and auditory behavior that is applied to all notifications in that channel. Then, users can change these settings and decide which notification channels from your app should be intrusive or visible at all, as Android developer docs states.

If you do not specify a notification channel, expo-notifications will create a fallback channel for you, named Miscellaneous. We encourage you to always ensure appropriate channels with informative names are set up for the application and to always send notifications to these channels.

Calling these methods is a no-op for platforms that do not support this feature (Android below version 8.0 (26) and iOS).

Custom notification icon and colors 
You can configure the notification.icon and notification.color keys in the project's app.json if you are using Expo Prebuild or by using the expo-notifications config plugin directly. These are build-time settings, so you'll need to recompile your native Android app with eas build -p android or npx expo run:android to see the changes.

For your notification icon, make sure you follow Google's design guidelines (the icon must be all white with a transparent background) or else it may not be displayed as intended.

You can also set a custom notification color per-notification directly in your NotificationContentInput under the color attribute.

API
import * as Notifications from 'expo-notifications';
Fetch tokens for push notifications
addPushTokenListener(listener)
Name	Type	Description
listener	PushTokenListener	
A function accepting a push token as an argument, it will be called whenever the push token changes.


In rare situations, a push token may be changed by the push notification service while the app is running. When a token is rolled, the old one becomes invalid and sending notifications to it will fail. A push token listener will let you handle this situation gracefully by registering the new token with your backend right away.

Returns:
EventSubscription

A Subscription object represents the subscription of the provided listener.

Example

import React from 'react';
import * as Notifications from 'expo-notifications';

import { registerDevicePushTokenAsync } from '../api';

export default function App() {
  React.useEffect(() => {
    const subscription = Notifications.addPushTokenListener(registerDevicePushTokenAsync);
    return () => subscription.remove();
  }, []);

  return (
    // Your app content
  );
}
getDevicePushTokenAsync()
Returns a native FCM, APNs token or a PushSubscription data that can be used with another push notification service.

Returns:
Promise<DevicePushToken>

getExpoPushTokenAsync(options)
Name	Type	Description
options
(optional)	ExpoPushTokenOptions	
Object allowing you to pass in push notification configuration.

Default: {}

Returns an Expo token that can be used to send a push notification to the device using Expo's push notifications service.

This method makes requests to the Expo's servers. It can get rejected in cases where the request itself fails (for example, due to the device being offline, experiencing a network timeout, or other HTTPS request failures). To provide offline support to your users, you should try/catch this method and implement retry logic to attempt to get the push token later, once the device is back online.

For Expo's backend to be able to send notifications to your app, you will need to provide it with push notification keys. For more information, see credentials in the push notifications setup.

Returns:
Promise<ExpoPushToken>

Returns a Promise that resolves to an object representing acquired push token.

Example

import * as Notifications from 'expo-notifications';

export async function registerForPushNotificationsAsync(userId: string) {
  const expoPushToken = await Notifications.getExpoPushTokenAsync({
   projectId: 'your-project-id',
  });

  await fetch('https://example.com/', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      userId,
      expoPushToken,
    }),
  });
}

Show More
removePushTokenSubscription(subscription)
Name	Type	Description
subscription	EventSubscription	
A subscription returned by addPushTokenListener method.


Removes a push token subscription returned by an addPushTokenListener call.

Returns:
void

Listen to notification events
addNotificationReceivedListener(listener)
Name	Type	Description
listener	(event: Notification) => void	
A function accepting a notification (Notification) as an argument.


Listeners registered by this method will be called whenever a notification is received while the app is running.

Returns:
EventSubscription

A Subscription object represents the subscription of the provided listener.

Example

import React from 'react';
import * as Notifications from 'expo-notifications';

export default function App() {
  React.useEffect(() => {
    const subscription = Notifications.addNotificationReceivedListener(notification => {
      console.log(notification);
    });
    return () => subscription.remove();
  }, []);

  return (
    // Your app content
  );
}
addNotificationResponseReceivedListener(listener)
Name	Type	Description
listener	(event: NotificationResponse) => void	
A function accepting notification response (NotificationResponse) as an argument.


Listeners registered by this method will be called whenever a user interacts with a notification (for example, taps on it).

Returns:
EventSubscription

A Subscription object represents the subscription of the provided listener.

Example

import React from 'react';
import { Linking } from 'react-native';
import * as Notifications from 'expo-notifications';

export default function Container() {
  React.useEffect(() => {
    const subscription = Notifications.addNotificationResponseReceivedListener(response => {
      const url = response.notification.request.content.data.url;
      Linking.openURL(url);
    });
    return () => subscription.remove();
  }, []);

  return (
    // Your app content
  );
}
addNotificationsDroppedListener(listener)
Name	Type	Description
listener	() => void	
A callback function.


Listeners registered by this method will be called whenever some notifications have been dropped by the server. Applicable only to Firebase Cloud Messaging which we use as a notifications service on Android. It corresponds to onDeletedMessages() callback. More information can be found in Firebase docs.

Returns:
EventSubscription

A Subscription object represents the subscription of the provided listener.

getLastNotificationResponseAsync()
Returns:
Promise<NotificationResponse | null>

removeNotificationSubscription(subscription)
Name	Type	Description
subscription	EventSubscription	
A subscription returned by addNotificationListener method.


Removes a notification subscription returned by an addNotificationListener call.

Returns:
void

useLastNotificationResponse()
A React hook always returns the notification response that was received most recently (a notification response designates an interaction with a notification, such as tapping on it).

If you don't want to use a hook, you can use Notifications.getLastNotificationResponseAsync() instead.

Returns:
undefined | null | NotificationResponse

The hook may return one of these three types/values:

undefined - until we're sure of what to return,
null - if no notification response has been received yet,
a NotificationResponse object - if a notification response was received.
Example

Responding to a notification tap by opening a URL that could be put into the notification's data (opening the URL is your responsibility and is not a part of the expo-notifications API):

import * as Notifications from 'expo-notifications';
import { Linking } from 'react-native';

export default function App() {
  const lastNotificationResponse = Notifications.useLastNotificationResponse();
  React.useEffect(() => {
    if (
      lastNotificationResponse &&
      lastNotificationResponse.notification.request.content.data.url &&
      lastNotificationResponse.actionIdentifier === Notifications.DEFAULT_ACTION_IDENTIFIER
    ) {
      Linking.openURL(lastNotificationResponse.notification.request.content.data.url);
    }
  }, [lastNotificationResponse]);
  return (
    // Your app content
  );
}

Show More
Handle incoming notifications when the app is in the foreground
setNotificationHandler(handler)
Name	Type	Description
handler	null | NotificationHandler	
A single parameter which should be either null (if you want to clear the handler) or a NotificationHandler object.


When a notification is received while the app is running, using this function you can set a callback that will decide whether the notification should be shown to the user or not.

When a notification is received, handleNotification is called with the incoming notification as an argument. The function should respond with a behavior object within 3 seconds, otherwise, the notification will be discarded. If the notification is handled successfully, handleSuccess is called with the identifier of the notification, otherwise (or on timeout) handleError will be called.

The default behavior when the handler is not set or does not respond in time is not to show the notification.

Returns:
void

Example

import * as Notifications from 'expo-notifications';

Notifications.setNotificationHandler({
  handleNotification: async () => ({
    shouldShowAlert: true,
    shouldPlaySound: false,
    shouldSetBadge: false,
  }),
});
Handle incoming notifications when the app is not in the foreground
registerTaskAsync(taskName)
Name	Type	Description
taskName	string	
The string you passed to TaskManager.defineTask as the taskName parameter.


When a notification is received while the app is backgrounded, using this function you can set a callback that will be run in response to that notification. Under the hood, this function is run using expo-task-manager. You must define the task first, with TaskManager.defineTask. Make sure you define it in the global scope.

The callback function you define with TaskManager.defineTask will receive an object with the following fields:

data: The remote payload delivered by either FCM (Android) or APNs (iOS). See PushNotificationTrigger for details.
error: The error (if any) that occurred during execution of the task.
executionInfo: JSON object of additional info related to the task, including the taskName.
Returns:
Promise<null>

Example

import * as TaskManager from 'expo-task-manager';
import * as Notifications from 'expo-notifications';

const BACKGROUND_NOTIFICATION_TASK = 'BACKGROUND-NOTIFICATION-TASK';

TaskManager.defineTask(BACKGROUND_NOTIFICATION_TASK, ({ data, error, executionInfo }) => {
  console.log('Received a notification in the background!');
  // Do something with the notification data
});

Notifications.registerTaskAsync(BACKGROUND_NOTIFICATION_TASK);
unregisterTaskAsync(taskName)
Name	Type	Description
taskName	string	
The string you passed to registerTaskAsync as the taskName parameter.


Used to unregister tasks registered with registerTaskAsync method.

Returns:
Promise<null>

Fetch information about notifications-related permissions
getPermissionsAsync()
Calling this function checks current permissions settings related to notifications. It lets you verify whether the app is currently allowed to display alerts, play sounds, etc. There is no user-facing effect of calling this.

Returns:
Promise<NotificationPermissionsStatus>

It returns a Promise resolving to an object represents permission settings (NotificationPermissionsStatus). On iOS, make sure you properly interpret the permissions response.

Example

import * as Notifications from 'expo-notifications';

export async function allowsNotificationsAsync() {
  const settings = await Notifications.getPermissionsAsync();
  return (
    settings.granted || settings.ios?.status === Notifications.IosAuthorizationStatus.PROVISIONAL
  );
}
requestPermissionsAsync(permissions)
Name	Type	Description
permissions
(optional)	NotificationPermissionsRequest	
An object representing configuration for the request scope.


Prompts the user for notification permissions according to request. Request defaults to asking the user to allow displaying alerts, setting badge count and playing sounds.

Returns:
Promise<NotificationPermissionsStatus>

It returns a Promise resolving to an object represents permission settings (NotificationPermissionsStatus). On iOS, make sure you properly interpret the permissions response.

Example

import * as Notifications from 'expo-notifications';

export function requestPermissionsAsync() {
  return await Notifications.requestPermissionsAsync({
    ios: {
      allowAlert: true,
      allowBadge: true,
      allowSound: true,
      allowAnnouncements: true,
    },
  });
}
Manage application badge icon
getBadgeCountAsync()
Fetches the number currently set as the badge of the app icon on device's home screen. A 0 value means that the badge is not displayed.

Note: Not all Android launchers support application badges. If the launcher does not support icon badges, the method will always resolve to 0.

Returns:
Promise<number>

Returns a Promise resolving to a number that represents the current badge of the app icon.

setBadgeCountAsync(badgeCount, options)
Name	Type	Description
badgeCount	number	
The count which should appear on the badge. A value of 0 will clear the badge.

options
(optional)	SetBadgeCountOptions	
An object of options configuring behavior applied.


Sets the badge of the app's icon to the specified number. Setting it to 0 clears the badge. On iOS, this method requires that you have requested the user's permission for allowBadge via requestPermissionsAsync, otherwise it will automatically return false.

Note: Not all Android launchers support application badges. If the launcher does not support icon badges, the method will resolve to false.

Returns:
Promise<boolean>

It returns a Promise resolving to a boolean representing whether the setting of the badge succeeded.

Schedule notifications
cancelAllScheduledNotificationsAsync()
Cancels all scheduled notifications.

Returns:
Promise<void>

A Promise that resolves once all the scheduled notifications are successfully canceled, or if there are no scheduled notifications.

cancelScheduledNotificationAsync(identifier)
Name	Type	Description
identifier	string	
The notification identifier with which scheduleNotificationAsync method resolved when the notification has been scheduled.


Cancels a single scheduled notification. The scheduled notification of given ID will not trigger.

Returns:
Promise<void>

A Promise resolves once the scheduled notification is successfully canceled or if there is no scheduled notification for a given identifier.

Example

import * as Notifications from 'expo-notifications';

async function scheduleAndCancel() {
  const identifier = await Notifications.scheduleNotificationAsync({
    content: {
      title: 'Hey!',
    },
    trigger: { seconds: 60, repeats: true },
  });
  await Notifications.cancelScheduledNotificationAsync(identifier);
}
getAllScheduledNotificationsAsync()
Fetches information about all scheduled notifications.

Returns:
Promise<NotificationRequest[]>

Returns a Promise resolving to an array of objects conforming to the Notification interface.

getNextTriggerDateAsync(trigger)
Name	Type	Description
trigger	SchedulableNotificationTriggerInput	
The schedulable notification trigger you would like to check next trigger date for (of type SchedulableNotificationTriggerInput).


Allows you to check what will be the next trigger date for given notification trigger input.

Returns:
Promise<number | null>

If the return value is null, the notification won't be triggered. Otherwise, the return value is the Unix timestamp in milliseconds at which the notification will be triggered.

Example

import * as Notifications from 'expo-notifications';

async function logNextTriggerDate() {
  try {
    const nextTriggerDate = await Notifications.getNextTriggerDateAsync({
      hour: 9,
      minute: 0,
    });
    console.log(nextTriggerDate === null ? 'No next trigger date' : new Date(nextTriggerDate));
  } catch (e) {
    console.warn(`Couldn't have calculated next trigger date: ${e}`);
  }
}
Deprecated This method has been deprecated in favor of using an explicit NotificationHandler and the scheduleNotificationAsync method. More information can be found in our FYI document.

presentNotificationAsync(content, identifier)
Name	Type	Description
content	NotificationContentInput	
An object representing the notification content.

identifier
(optional)	string	-

Schedules a notification for immediate trigger.

Returns:
Promise<string>

It returns a Promise resolving with the notification's identifier once the notification is successfully scheduled for immediate display.

scheduleNotificationAsync(request)
Name	Type	Description
request	NotificationRequestInput	
An object describing the notification to be triggered.


Schedules a notification to be triggered in the future.

Note: Please note that this does not mean that the notification will be presented when it is triggered. For the notification to be presented you have to set a notification handler with setNotificationHandler that will return an appropriate notification behavior. For more information see the example below.

Returns:
Promise<string>

Returns a Promise resolving to a string which is a notification identifier you can later use to cancel the notification or to identify an incoming notification.

Example

Schedule the notification that will trigger once, in one minute from now
import * as Notifications from 'expo-notifications';

Notifications.scheduleNotificationAsync({
  content: {
    title: "Time's up!",
    body: 'Change sides!',
  },
  trigger: {
    seconds: 60,
  },
});
Schedule the notification that will trigger repeatedly, every 20 minutes
import * as Notifications from 'expo-notifications';

Notifications.scheduleNotificationAsync({
  content: {
    title: 'Remember to drink water!',
  },
  trigger: {
    seconds: 60 * 20,
    repeats: true,
  },
});
Schedule the notification that will trigger once, at the beginning of next hour
import * as Notifications from 'expo-notifications';

const trigger = new Date(Date.now() + 60 * 60 * 1000);
trigger.setMinutes(0);
trigger.setSeconds(0);

Notifications.scheduleNotificationAsync({
  content: {
    title: 'Happy new hour!',
  },
  trigger,
});
Dismiss notifications
dismissAllNotificationsAsync()
Removes all application's notifications displayed in the notification tray (Notification Center).

Returns:
Promise<void>

A Promise which resolves once the request to dismiss the notifications is successfully dispatched to the notifications manager.

dismissNotificationAsync(notificationIdentifier)
Name	Type	Description
notificationIdentifier	string	
The notification identifier, obtained either via setNotificationHandler method or in the listener added with addNotificationReceivedListener.


Removes notification displayed in the notification tray (Notification Center).

Returns:
Promise<void>

A Promise which resolves once the request to dismiss the notification is successfully dispatched to the notifications manager.

getPresentedNotificationsAsync()
Fetches information about all notifications present in the notification tray (Notification Center).

This method is not supported on Android below 6.0 (API level 23) – on these devices it will resolve to an empty array.

Returns:
Promise<Notification[]>

A Promise which resolves with a list of notifications (Notification) currently present in the notification tray (Notification Center).

Manage notification channels (Android-specific)
Only for: 

deleteNotificationChannelAsync(channelId)
Name	Type	Description
channelId	string	
The channel identifier.


Removes the notification channel.

Returns:
Promise<void>

A Promise which resolving once the channel is removed (or if there was no channel for given identifier).

Only for: 

deleteNotificationChannelGroupAsync(groupId)
Name	Type	Description
groupId	string	
The channel group identifier.


Removes the notification channel group and all notification channels that belong to it.

Returns:
Promise<void>

A Promise which resolves once the channel group is removed (or if there was no channel group for given identifier).

Only for: 

getNotificationChannelAsync(channelId)
Name	Type	Description
channelId	string	
The channel's identifier.


Fetches information about a single notification channel.

Returns:
Promise<NotificationChannel | null>

A Promise which resolves to the channel object (of type NotificationChannel) or to null if there was no channel found for this identifier. On platforms that do not support notification channels, it will always resolve to null.

Only for: 

getNotificationChannelGroupAsync(groupId)
Name	Type	Description
groupId	string	
The channel group's identifier.


Fetches information about a single notification channel group.

Returns:
Promise<NotificationChannelGroup | null>

A Promise which resolves to the channel group object (of type NotificationChannelGroup) or to null if there was no channel group found for this identifier. On platforms that do not support notification channels, it will always resolve to null.

Only for: 

getNotificationChannelGroupsAsync()
Fetches information about all known notification channel groups.

Returns:
Promise<NotificationChannelGroup[]>

A Promise which resoles to an array of channel groups. On platforms that do not support notification channel groups, it will always resolve to an empty array.

Only for: 

getNotificationChannelsAsync()
Fetches information about all known notification channels.

Returns:
Promise<NotificationChannel[]>

A Promise which resolves to an array of channels. On platforms that do not support notification channels, it will always resolve to an empty array.

Only for: 

setNotificationChannelAsync(channelId, channel)
Name	Type	Description
channelId	string	
The channel identifier.

channel	NotificationChannelInput	
Object representing the channel's configuration.


Assigns the channel configuration to a channel of a specified name (creating it if need be). This method lets you assign given notification channel to a notification channel group.

Note: For some settings to be applied on all Android versions, it may be necessary to duplicate the configuration across both a single notification and its respective notification channel.

For example, for a notification to play a custom sound on Android versions below 8.0, the custom notification sound has to be set on the notification (through the NotificationContentInput), and for the custom sound to play on Android versions above 8.0, the relevant notification channel must have the custom sound configured (through the NotificationChannelInput). For more information, see Set custom notification sounds on Android.

Returns:
Promise<NotificationChannel | null>

A Promise which resolving to the object (of type NotificationChannel) describing the modified channel or to null if the platform does not support notification channels.

Only for: 

setNotificationChannelGroupAsync(groupId, group)
Name	Type	Description
groupId	string	
The channel group's identifier.

group	NotificationChannelGroupInput	
Object representing the channel group configuration.


Assigns the channel group configuration to a channel group of a specified name (creating it if need be).

Returns:
Promise<NotificationChannelGroup | null>

A Promise resolving to the object (of type NotificationChannelGroup) describing the modified channel group or to null if the platform does not support notification channels.

Manage notification categories (interactive notifications)
Only for: 

deleteNotificationCategoryAsync(identifier)
Name	Type	Description
identifier	string	
Identifier initially provided to setNotificationCategoryAsync when creating the category.


Deletes the category associated with the provided identifier.

Returns:
Promise<boolean>

A Promise which resolves to true if the category was successfully deleted, or false if it was not. An example of when this method would return false is if you try to delete a category that doesn't exist.

Only for: 

getNotificationCategoriesAsync()
Fetches information about all known notification categories.

Returns:
Promise<NotificationCategory[]>

A Promise which resolves to an array of NotificationCategorys. On platforms that do not support notification channels, it will always resolve to an empty array.

Only for: 

setNotificationCategoryAsync(identifier, actions, options)
Name	Type	Description
identifier	string	
A string to associate as the ID of this category. You will pass this string in as the categoryIdentifier in your NotificationContent to associate a notification with this category.

Don't use the characters : or - in your category identifier. If you do, categories might not work as expected.

actions	NotificationAction[]	
An array of NotificationAction, which describe the actions associated with this category.

options
(optional)	NotificationCategoryOptions	
An optional object of additional configuration options for your category.


Sets the new notification category.

Returns:
Promise<NotificationCategory>

A Promise which resolves to the category you just have created.

Constants
Notifications.DEFAULT_ACTION_IDENTIFIER
Type: 'expo.modules.notifications.actions.DEFAULT'

Methods
Notifications.setAutoServerRegistrationEnabledAsync(enabled)
Name	Type
enabled	boolean

Sets the registration information so that the device push token gets pushed to the given registration endpoint

Returns:
Promise<void>

Notifications.unregisterForNotificationsAsync()
Returns:
Promise<void>

Interfaces
AudioAttributes
AudioAttributes Properties

Name	Type	Description
contentType	AndroidAudioContentType	-
flags	
{
  enforceAudibility: boolean, 
  requestHardwareAudioVideoSynchronization: boolean
}
-
usage	AndroidAudioUsage	-

Only for: 

BeaconRegion
Extends: Region

A region used to detect the presence of iBeacon devices. Based on Core Location CLBeaconRegion class.

BeaconRegion Properties

Name	Type	Description
beaconIdentityConstraint
(optional)	
{
  major: null | number, 
  minor: null | number, 
  uuid: string
}
The beacon identity constraint that defines the beacon region.

major	null | number	
The major value from the beacon identity constraint that defines the beacon region.

minor	null | number	
The minor value from the beacon identity constraint that defines the beacon region.

notifyEntryStateOnDisplay	boolean	
A Boolean value that indicates whether Core Location sends beacon notifications when the device’s display is on.

type	'beacon'	-
uuid
(optional)	string	
The UUID value from the beacon identity constraint that defines the beacon region.


Only for: 

CalendarNotificationTrigger
A trigger related to a UNCalendarNotificationTrigger.

CalendarNotificationTrigger Properties

Name	Type	Description
dateComponents	
{
  calendar: string, 
  day: number, 
  era: number, 
  hour: number, 
  isLeapMonth: boolean, 
  minute: number, 
  month: number, 
  nanosecond: number, 
  quarter: number, 
  second: number, 
  timeZone: string, 
  weekOfMonth: number, 
  weekOfYear: number, 
  weekday: number, 
  weekdayOrdinal: number, 
  year: number, 
  yearForWeekOfYear: number
}
-
repeats	boolean	-
type	'calendar'	-

Only for: 

CircularRegion
Extends: Region

A circular geographic region, specified as a center point and radius. Based on Core Location CLCircularRegion class.

CircularRegion Properties

Name	Type	Description
center	
{
  latitude: number, 
  longitude: number
}
The center point of the geographic area.

radius	number	
The radius (measured in meters) that defines the geographic area’s outer boundary.

type	'circular'	-

Only for: 

DailyNotificationTrigger
A trigger related to a daily notification.

The same functionality will be achieved on iOS with a CalendarNotificationTrigger.

DailyNotificationTrigger Properties

Name	Type	Description
hour	number	-
minute	number	-
type	'daily'	-

DailyTriggerInput
A trigger that will cause the notification to be delivered once per day.

DailyTriggerInput Properties

Name	Type	Description
channelId
(optional)	string	-
hour	number	-
minute	number	-
repeats	true	-

ExpoPushToken
Borrowing structure from DevicePushToken a little. You can use the data value to send notifications via Expo Notifications service.

ExpoPushToken Properties

Name	Type	Description
data	string	
The acquired push token.

type	'expo'	
Always set to "expo".


ExpoPushTokenOptions
ExpoPushTokenOptions Properties

Name	Type	Description
applicationId
(optional)	string	
The ID of the application to which the token should be attributed. Defaults to Application.applicationId exposed by expo-application.

baseUrl
(optional)	string	
Endpoint URL override.

development
(optional)	boolean	
Only for: 

Makes sense only on iOS, where there are two push notification services: "sandbox" and "production". This defines whether the push token is supposed to be used with the sandbox platform notification service. Defaults to Application.getIosPushNotificationServiceEnvironmentAsync() exposed by expo-application or false. Most probably you won't need to customize that. You may want to customize that if you don't want to install expo-application and still use the sandbox APNs.

deviceId
(optional)	string	-
devicePushToken
(optional)	DevicePushToken	
The device push token with which to register at the backend. Defaults to a token fetched with getDevicePushTokenAsync().

projectId
(optional)	string	
The ID of the project to which the token should be attributed. Defaults to Constants.expoConfig.extra.eas.projectId exposed by expo-constants.

When using EAS Build, this value is automatically set. However, it is recommended to set it manually. Once you have EAS Build configured, you can find the value in app.json under extra.eas.projectId. You can copy and paste it into your code. If you are not using EAS Build, it will fallback to Constants.expoConfig?.extra?.eas?.projectId.

type
(optional)	string	
Request body override.

url
(optional)	string	
Request URL override.


FirebaseRemoteMessage
A Firebase RemoteMessage that caused the notification to be delivered to the app.

FirebaseRemoteMessage Properties

Name	Type	Description
collapseKey	null | string	-
data	Record<string, string>	-
from	null | string	-
messageId	null | string	-
messageType	null | string	-
notification	null | FirebaseRemoteMessageNotification	-
originalPriority	number	-
priority	number	-
sentTime	number	-
to	null | string	-
ttl	number	-

FirebaseRemoteMessageNotification
FirebaseRemoteMessageNotification Properties

Name	Type	Description
body	null | string	-
bodyLocalizationArgs	null | string[]	-
bodyLocalizationKey	null | string	-
channelId	null | string	-
clickAction	null | string	-
color	null | string	-
eventTime	null | number	-
icon	null | string	-
imageUrl	null | string	-
lightSettings	null | number[]	-
link	null | string	-
localOnly	boolean	-
notificationCount	null | number	-
notificationPriority	null | number	-
sound	null | string	-
sticky	boolean	-
tag	null | string	-
ticker	null | string	-
title	null | string	-
titleLocalizationArgs	null | string[]	-
titleLocalizationKey	null | string	-
usesDefaultLightSettings	boolean	-
usesDefaultSound	boolean	-
usesDefaultVibrateSettings	boolean	-
vibrateTimings	null | number[]	-
visibility	null | number	-

IosNotificationPermissionsRequest
Available configuration for permission request on iOS platform. See Apple documentation for UNAuthorizationOptions to learn more.

IosNotificationPermissionsRequest Properties

Name	Type	Description
allowAlert
(optional)	boolean	
The ability to display alerts.

allowAnnouncements
(optional)	boolean	
Deprecated
The ability for Siri to automatically read out messages over AirPods.

allowBadge
(optional)	boolean	
The ability to update the app’s badge.

allowCriticalAlerts
(optional)	boolean	
The ability to play sounds for critical alerts.

allowDisplayInCarPlay
(optional)	boolean	
The ability to display notifications in a CarPlay environment.

allowProvisional
(optional)	boolean	
The ability to post noninterrupting notifications provisionally to the Notification Center.

allowSound
(optional)	boolean	
The ability to play sounds.

provideAppNotificationSettings
(optional)	boolean	
An option indicating the system should display a button for in-app notification settings.


Only for: 

LocationNotificationTrigger
A trigger related to a UNLocationNotificationTrigger.

LocationNotificationTrigger Properties

Name	Type	Description
region	CircularRegion | BeaconRegion	-
repeats	boolean	-
type	'location'	-

NativeDevicePushToken
NativeDevicePushToken Properties

Name	Type	Description
data	string	-
type	'ios' | 'android'	-

Notification
An object represents a single notification that has been triggered by some request (NotificationRequest) at some point in time.

Notification Properties

Name	Type	Description
date	number	-
request	NotificationRequest	-

NotificationAction
NotificationAction Properties

Name	Type	Description
buttonTitle	string	
The title of the button triggering this action.

identifier	string	
A unique string that identifies this action. If a user takes this action (for example, selects this button in the system's Notification UI), your app will receive this actionIdentifier via the NotificationResponseReceivedListener.

options
(optional)	
{
  isAuthenticationRequired: boolean, 
  isDestructive: boolean, 
  opensAppToForeground: boolean
}
Object representing the additional configuration options.

textInput
(optional)	
{
  placeholder: string, 
  submitButtonTitle: string
}
Object which, if provided, will result in a button that prompts the user for a text response.


NotificationBehavior
An object represents behavior that should be applied to the incoming notification.

On Android, setting shouldPlaySound: false will result in the drop-down notification alert not showing, no matter what the priority is. This setting will also override any channel-specific sounds you may have configured.

NotificationBehavior Properties

Name	Type	Description
priority
(optional)	AndroidNotificationPriority	-
shouldPlaySound	boolean	-
shouldSetBadge	boolean	-
shouldShowAlert	boolean	-

NotificationCategory
NotificationCategory Properties

Name	Type	Description
actions	NotificationAction[]	-
identifier	string	-
options
(optional)	NotificationCategoryOptions	-

Only for: 

NotificationChannel
An object represents a notification channel.

NotificationChannel Properties

Name	Type	Description
audioAttributes	AudioAttributes	-
bypassDnd	boolean	-
description	null | string	-
enableLights	boolean	-
enableVibrate	boolean	-
groupId
(optional)	null | string	-
id	string	-
importance	AndroidImportance	-
lightColor	string	-
lockscreenVisibility	AndroidNotificationVisibility	-
name	null | string	-
showBadge	boolean	-
sound	null | 'default' | 'custom'	-
vibrationPattern	null | number[]	-

Only for: 

NotificationChannelGroup
An object represents a notification channel group.

NotificationChannelGroup Properties

Name	Type	Description
channels	NotificationChannel[]	-
description
(optional)	null | string	-
id	string	-
isBlocked
(optional)	boolean	-
name	null | string	-

Only for: 

NotificationChannelGroupInput
An object represents a notification channel group to be set.

NotificationChannelGroupInput Properties

Name	Type	Description
description
(optional)	null | string	-
name	null | string	-

NotificationChannelGroupManager
Extends: ProxyNativeModule

NotificationChannelGroupManager Properties

Name	Type	Description
deleteNotificationChannelGroupAsync
(optional)	(groupId: string) => Promise<void>	-
getNotificationChannelGroupAsync
(optional)	(groupId: string) => Promise<null | NotificationChannelGroup>	-
getNotificationChannelGroupsAsync
(optional)	() => Promise<NotificationChannelGroup[]>	-
setNotificationChannelGroupAsync
(optional)	(groupId: string, group: NotificationChannelGroupInput) => Promise<null | NotificationChannelGroup>	-

NotificationChannelManager
Extends: ProxyNativeModule

NotificationChannelManager Properties

Name	Type	Description
deleteNotificationChannelAsync
(optional)	(channelId: string) => Promise<void>	-
getNotificationChannelAsync
(optional)	(channelId: string) => Promise<null | NotificationChannel>	-
getNotificationChannelsAsync
(optional)	() => Promise<null | NotificationChannel[]>	-
setNotificationChannelAsync
(optional)	(channelId: string, channelConfiguration: NotificationChannelInput) => Promise<null | NotificationChannel>	-

NotificationHandler
NotificationHandler Properties

Name	Type	Description
handleError
(optional)	(notificationId: string, error: NotificationHandlingError) => void	
A function called whenever handling of an incoming notification fails.

handleNotification	(notification: Notification) => Promise<NotificationBehavior>	
A function accepting an incoming notification returning a Promise resolving to a behavior (NotificationBehavior) applicable to the notification

handleSuccess
(optional)	(notificationId: string) => void	
A function called whenever an incoming notification is handled successfully.


NotificationPermissionsRequest
An interface representing the permissions request scope configuration. Each option corresponds to a different native platform authorization option.

NotificationPermissionsRequest Properties

Name	Type	Description
android
(optional)	object	
On Android, all available permissions are granted by default, and if a user declines any permission, an app cannot prompt the user to change.

ios
(optional)	IosNotificationPermissionsRequest	
Available configuration for permission request on iOS platform.


NotificationPermissionsStatus
Extends: PermissionResponse

An object obtained by permissions get and request functions.

NotificationPermissionsStatus Properties

Name	Type	Description
android
(optional)	
{
  importance: number, 
  interruptionFilter: number
}
-
ios
(optional)	
{
  alertStyle: IosAlertStyle, 
  allowsAlert: null | boolean, 
  allowsAnnouncements: null | boolean, 
  allowsBadge: null | boolean, 
  allowsCriticalAlerts: null | boolean, 
  allowsDisplayInCarPlay: null | boolean, 
  allowsDisplayInNotificationCenter: null | boolean, 
  allowsDisplayOnLockScreen: null | boolean, 
  allowsPreviews: IosAllowsPreviews, 
  allowsSound: null | boolean, 
  providesAppNotificationSettings: boolean, 
  status: IosAuthorizationStatus
}
-

NotificationRequest
An object represents a request to present a notification. It has content — how it's being represented, and a trigger — what triggers the notification. Many notifications (Notification) may be triggered with the same request (for example, a repeating notification).

NotificationRequest Properties

Name	Type	Description
content	NotificationContent	-
identifier	string	-
trigger	NotificationTrigger	-

NotificationRequestInput
An object represents a notification request you can pass into scheduleNotificationAsync.

NotificationRequestInput Properties

Name	Type	Description
content	NotificationContentInput	-
identifier
(optional)	string	-
trigger	NotificationTriggerInput	-

NotificationResponse
An object represents user's interaction with the notification.

Note: If the user taps on a notification actionIdentifier will be equal to Notifications.DEFAULT_ACTION_IDENTIFIER.

NotificationResponse Properties

Name	Type	Description
actionIdentifier	string	-
notification	Notification	-
userText
(optional)	string	-

PermissionResponse
An object obtained by permissions get and request functions.

PermissionResponse Properties

Name	Type	Description
canAskAgain	boolean	
Indicates if user can be asked again for specific permission. If not, one should be directed to the Settings app in order to enable/disable the permission.

expires	PermissionExpiration	
Determines time when the permission expires.

granted	boolean	
A convenience boolean that indicates if the permission is granted.

status	PermissionStatus	
Determines the status of the permission.


Only for: 

Region
The region used to determine when the system sends the notification.

Region Properties

Name	Type	Description
identifier	string	
The identifier for the region object.

notifyOnEntry	boolean	
A Boolean indicating that notifications are generated upon entry into the region.

notifyOnExit	boolean	
A Boolean indicating that notifications are generated upon exit from the region.

type	string	-

TimeIntervalNotificationTrigger
A trigger related to an elapsed time interval. May be repeating (see repeats field).

TimeIntervalNotificationTrigger Properties

Name	Type	Description
repeats	boolean	-
seconds	number	-
type	'timeInterval'	-

TimeIntervalTriggerInput
A trigger that will cause the notification to be delivered once or many times (depends on the repeats field) after seconds time elapse.

On iOS, when repeats is true, the time interval must be 60 seconds or greater. Otherwise, the notification won't be triggered.

TimeIntervalTriggerInput Properties

Name	Type	Description
channelId
(optional)	string	-
repeats
(optional)	boolean	-
seconds	number	-

UnknownNotificationTrigger
Represents a notification trigger that is unknown to expo-notifications and that it didn't know how to serialize for JS.

UnknownNotificationTrigger Properties

Name	Type	Description
type	'unknown'	-

Only for: 

WeeklyNotificationTrigger
A trigger related to a weekly notification.

The same functionality will be achieved on iOS with a CalendarNotificationTrigger.

WeeklyNotificationTrigger Properties

Name	Type	Description
hour	number	-
minute	number	-
type	'weekly'	-
weekday	number	-

WeeklyTriggerInput
A trigger that will cause the notification to be delivered once every week.

Note: Weekdays are specified with a number from 1 through 7, with 1 indicating Sunday.

WeeklyTriggerInput Properties

Name	Type	Description
channelId
(optional)	string	-
hour	number	-
minute	number	-
repeats	true	-
weekday	number	-

Only for: 

YearlyNotificationTrigger
A trigger related to a yearly notification.

The same functionality will be achieved on iOS with a CalendarNotificationTrigger.

YearlyNotificationTrigger Properties

Name	Type	Description
day	number	-
hour	number	-
minute	number	-
month	number	-
type	'yearly'	-

YearlyTriggerInput
A trigger that will cause the notification to be delivered once every year.

Note: all properties are specified in JavaScript Date's ranges.

YearlyTriggerInput Properties

Name	Type	Description
channelId
(optional)	string	-
day	number	-
hour	number	-
minute	number	-
month	number	-
repeats	true	-

Types
AudioAttributesInput
Type: Partial<AudioAttributes>

Only for: 

CalendarTriggerInput
A trigger that will cause the notification to be delivered once or many times when the date components match the specified values. Corresponds to native UNCalendarNotificationTrigger.

Type: CalendarTriggerInputValue extended by:


Name	Type	Description
channelId
(optional)	string	-
repeats
(optional)	boolean	-
CalendarTriggerInputValue
Name	Type	Description
day
(optional)	number	-
hour
(optional)	number	-
minute
(optional)	number	-
month
(optional)	number	-
second
(optional)	number	-
timezone
(optional)	string	-
weekOfMonth
(optional)	number	-
weekOfYear
(optional)	number	-
weekday
(optional)	number	-
weekdayOrdinal
(optional)	number	-
year
(optional)	number	-
ChannelAwareTriggerInput
A trigger that will cause the notification to be delivered immediately.

Name	Type	Description
channelId	string	-
DateTriggerInput
A trigger that will cause the notification to be delivered once at the specified Date. If you pass in a number it will be interpreted as a Unix timestamp.

Type: Date or number or object shaped as below:


Name	Type	Description
channelId
(optional)	string	-
date	Date | number	-
DevicePushToken
Literal Type: multiple types

In simple terms, an object of type: Platform.OS and data: any. The data type depends on the environment - on a native device it will be a string, which you can then use to send notifications via Firebase Cloud Messaging (Android) or APNs (iOS).

Acceptable values are: ExplicitlySupportedDevicePushToken | ImplicitlySupportedDevicePushToken

ExplicitlySupportedDevicePushToken
Type: NativeDevicePushToken

ImplicitlySupportedDevicePushToken
Name	Type	Description
data	any	
The push token as a string for a native platform.

type	Exclude<Platform.OS, ExplicitlySupportedDevicePushToken['type']>	
Either android or ios.

NativeNotificationPermissionsRequest
Literal Type: multiple types

Acceptable values are: IosNotificationPermissionsRequest | object

Only for: 

NotificationCategoryOptions
Name	Type	Description
allowAnnouncement
(optional)	boolean	
A boolean indicating whether to allow notifications to be automatically read by Siri when the user is using AirPods.

Default: false
allowInCarPlay
(optional)	boolean	
A boolean indicating whether to allow CarPlay to display notifications of this type. Apps must be approved for CarPlay to make use of this feature.

Default: false
categorySummaryFormat
(optional)	string	
A format string for the summary description used when the system groups the category’s notifications.

customDismissAction
(optional)	boolean	
A boolean indicating whether to send actions for handling when the notification is dismissed (the user must explicitly dismiss the notification interface - ignoring a notification or flicking away a notification banner does not trigger this action).

Default: false
intentIdentifiers
(optional)	string[]	
Array of Intent Class Identifiers. When a notification is delivered, the presence of an intent identifier lets the system know that the notification is potentially related to the handling of a request made through Siri.

Default: []
previewPlaceholder
(optional)	string	
Customizable placeholder for the notification preview text. This is shown if the user has disabled notification previews for the app. Defaults to the localized iOS system default placeholder (Notification).

showSubtitle
(optional)	boolean	
A boolean indicating whether to show the notification's subtitle, even if the user has disabled notification previews for the app.

Default: false
showTitle
(optional)	boolean	
A boolean indicating whether to show the notification's title, even if the user has disabled notification previews for the app.

Default: false
Only for: 

NotificationChannelInput
Type: RequiredBy<Omit<NotificationChannel, 'id' | 'audioAttributes' | 'sound'> & { audioAttributes: AudioAttributesInput, sound: string | null }, 'name' | 'importance'>

An object represents a notification channel to be set.

NotificationContent
An object represents notification's content.

Type: NotificationContentIos | NotificationContentAndroid extended by:


Name	Type	Description
body	string | null	
Notification body - the main content of the notification.

data	Record<string, any>	
Data associated with the notification, not displayed

sound	'default' | 'defaultCritical' | 'custom' | null	-
subtitle	string | null	
On Android: subText - the display depends on the device.

On iOS: subtitle - the bold text displayed between title and the rest of the content.

title	string | null	
Notification title - the bold text displayed above the rest of the content.

NotificationContentAndroid
See Android developer documentation for more information on specific fields.

Name	Type	Description
badge
(optional)	number	
Application badge number associated with the notification.

color
(optional)	string	
Accent color (in #AARRGGBB or #RRGGBB format) to be applied by the standard Style templates when presenting this notification.

priority
(optional)	AndroidNotificationPriority	
Relative priority for this notification. Priority is an indication of how much of the user's valuable attention should be consumed by this notification. Low-priority notifications may be hidden from the user in certain situations, while the user might be interrupted for a higher-priority notification. The system will make a determination about how to interpret this priority when presenting the notification.

vibrationPattern
(optional)	number[]	
The pattern with which to vibrate.

Only for: 

NotificationContentAttachmentIos
Name	Type	Description
hideThumbnail
(optional)	boolean	-
identifier	string | null	-
thumbnailClipArea
(optional)	
{
  height: number, 
  width: number, 
  x: number, 
  y: number
}
-
thumbnailTime
(optional)	number	-
type	string | null	-
typeHint
(optional)	string	-
url	string | null	-
NotificationContentInput
An object represents notification content that you pass in to presentNotificationAsync or as a part of NotificationRequestInput.

Name	Type	Description
attachments
(optional)	NotificationContentAttachmentIos[]	
Only for: 

The visual and audio attachments to display alongside the notification’s main content.

autoDismiss
(optional)	boolean	
Only for: 

If set to false, the notification will not be automatically dismissed when clicked. The setting will be used when the value is not provided or is invalid is set to true, and the notification will be dismissed automatically anyway. Corresponds directly to Android's setAutoCancel behavior.

See Android developer documentation for more details.

badge
(optional)	number	
Application badge number associated with the notification.

body
(optional)	string | null	
The main content of the notification.

categoryIdentifier
(optional)	string	
Only for: 

The identifier of the notification’s category.

color
(optional)	string	
Only for: 

Accent color (in #AARRGGBB or #RRGGBB format) to be applied by the standard Style templates when presenting this notification.

data
(optional)	Record<string, any>	
Data associated with the notification, not displayed.

interruptionLevel
(optional)	'passive' | 'active' | 'timeSensitive' | 'critical'	-
launchImageName
(optional)	string	
The name of the image or storyboard to use when your app launches because of the notification.

priority
(optional)	string	
Only for: 

Relative priority for this notification. Priority is an indication of how much of the user's valuable attention should be consumed by this notification. Low-priority notifications may be hidden from the user in certain situations, while the user might be interrupted for a higher-priority notification. The system will make a determination about how to interpret this priority when presenting the notification.

sound
(optional)	boolean | string	-
sticky
(optional)	boolean	
Only for: 

If set to true, the notification cannot be dismissed by swipe. This setting defaults to false if not provided or is invalid. Corresponds directly do Android's isOngoing behavior. In Firebase terms this property of a notification is called sticky.

See Android developer documentation and Firebase documentation for more details.

subtitle
(optional)	string | null	
On Android: subText - the display depends on the device.

On iOS: subtitle - the bold text displayed between title and the rest of the content.

title
(optional)	string | null	
Notification title - the bold text displayed above the rest of the content.

vibrate
(optional)	number[]	
Only for: 

The pattern with which to vibrate.

NotificationContentIos
See Apple documentation for more information on specific fields.

Name	Type	Description
attachments	NotificationContentAttachmentIos[]	
The visual and audio attachments to display alongside the notification’s main content.

badge	number | null	
The number that your app’s icon displays.

categoryIdentifier	string | null	
The identifier of the notification’s category.

interruptionLevel
(optional)	'passive' | 'active' | 'timeSensitive' | 'critical'	-
launchImageName	string | null	
The name of the image or storyboard to use when your app launches because of the notification.

summaryArgument
(optional)	string | null	
The text the system adds to the notification summary to provide additional context.

summaryArgumentCount
(optional)	number	
The number the system adds to the notification summary when the notification represents multiple items.

targetContentIdentifier
(optional)	string	
The value your app uses to determine which scene to display to handle the notification.

threadIdentifier	string | null	
The identifier that groups related notifications.

NotificationHandlingError
Literal Type: multiple types

Acceptable values are: NotificationTimeoutError | Error

NotificationTrigger
Literal Type: multiple types

A union type containing different triggers which may cause the notification to be delivered to the application.

Acceptable values are: PushNotificationTrigger | CalendarNotificationTrigger | LocationNotificationTrigger | TimeIntervalNotificationTrigger | DailyNotificationTrigger | WeeklyNotificationTrigger | YearlyNotificationTrigger | UnknownNotificationTrigger

NotificationTriggerInput
Literal Type: multiple types

A type represents possible triggers with which you can schedule notifications. A null trigger means that the notification should be scheduled for delivery immediately.

Acceptable values are: null | ChannelAwareTriggerInput | SchedulableNotificationTriggerInput

PermissionExpiration
Literal Type: multiple types

Permission expiration time. Currently, all permissions are granted permanently.

Acceptable values are: 'never' | number

PermissionHookOptions
Literal Type: multiple types

Acceptable values are: PermissionHookBehavior | Options

PushNotificationTrigger
An object represents a notification delivered by a push notification system.

On Android under remoteMessage field a JS version of the Firebase RemoteMessage may be accessed. On iOS under payload you may find full contents of UNNotificationContent's userInfo, for example remote notification payload.

Name	Type	Description
payload
(optional)	Record<string, unknown>	-
remoteMessage
(optional)	FirebaseRemoteMessage	-
type	'push'	-
PushTokenListener()
A function accepting a device push token (DevicePushToken) as an argument.

Note: You should not call getDevicePushTokenAsync inside this function, as it triggers the listener and may lead to an infinite loop.

Name	Type
token	DevicePushToken
RequiredBy
Literal Type: multiple types

Acceptable values are: Partial<Omit<T, K>> | Required<Pick<T, K>>

SchedulableNotificationTriggerInput
Literal Type: multiple types

A type represents time-based, schedulable triggers. For these triggers you can check the next trigger date with getNextTriggerDateAsync.

Acceptable values are: DateTriggerInput | TimeIntervalTriggerInput | DailyTriggerInput | WeeklyTriggerInput | YearlyTriggerInput | CalendarTriggerInput

Subscription
A subscription object that allows to conveniently remove an event listener from the emitter.

Name	Type	Description
remove	() => void	
Removes an event listener for which the subscription has been created. After calling this function, the listener will no longer receive any events from the emitter.

Enums
AndroidAudioContentType
AndroidAudioContentType Values

UNKNOWN
AndroidAudioContentType.UNKNOWN ＝ 0
SPEECH
AndroidAudioContentType.SPEECH ＝ 1
MUSIC
AndroidAudioContentType.MUSIC ＝ 2
MOVIE
AndroidAudioContentType.MOVIE ＝ 3
SONIFICATION
AndroidAudioContentType.SONIFICATION ＝ 4
AndroidAudioUsage
AndroidAudioUsage Values

UNKNOWN
AndroidAudioUsage.UNKNOWN ＝ 0
MEDIA
AndroidAudioUsage.MEDIA ＝ 1
VOICE_COMMUNICATION
AndroidAudioUsage.VOICE_COMMUNICATION ＝ 2
VOICE_COMMUNICATION_SIGNALLING
AndroidAudioUsage.VOICE_COMMUNICATION_SIGNALLING ＝ 3
ALARM
AndroidAudioUsage.ALARM ＝ 4
NOTIFICATION
AndroidAudioUsage.NOTIFICATION ＝ 5
NOTIFICATION_RINGTONE
AndroidAudioUsage.NOTIFICATION_RINGTONE ＝ 6
NOTIFICATION_COMMUNICATION_REQUEST
AndroidAudioUsage.NOTIFICATION_COMMUNICATION_REQUEST ＝ 7
NOTIFICATION_COMMUNICATION_INSTANT
AndroidAudioUsage.NOTIFICATION_COMMUNICATION_INSTANT ＝ 8
NOTIFICATION_COMMUNICATION_DELAYED
AndroidAudioUsage.NOTIFICATION_COMMUNICATION_DELAYED ＝ 9
NOTIFICATION_EVENT
AndroidAudioUsage.NOTIFICATION_EVENT ＝ 10
ASSISTANCE_ACCESSIBILITY
AndroidAudioUsage.ASSISTANCE_ACCESSIBILITY ＝ 11
ASSISTANCE_NAVIGATION_GUIDANCE
AndroidAudioUsage.ASSISTANCE_NAVIGATION_GUIDANCE ＝ 12
ASSISTANCE_SONIFICATION
AndroidAudioUsage.ASSISTANCE_SONIFICATION ＝ 13
GAME
AndroidAudioUsage.GAME ＝ 14
AndroidImportance
AndroidImportance Values

UNKNOWN
AndroidImportance.UNKNOWN ＝ 0
UNSPECIFIED
AndroidImportance.UNSPECIFIED ＝ 1
NONE
AndroidImportance.NONE ＝ 2
MIN
AndroidImportance.MIN ＝ 3
LOW
AndroidImportance.LOW ＝ 4
Deprecated Use DEFAULT instead.

DEEFAULT
AndroidImportance.DEEFAULT ＝ 5
DEFAULT
AndroidImportance.DEFAULT ＝ 5
HIGH
AndroidImportance.HIGH ＝ 6
MAX
AndroidImportance.MAX ＝ 7
AndroidNotificationPriority
An enum corresponding to values appropriate for Android's Notification#priority field.

AndroidNotificationPriority Values

DEFAULT
AndroidNotificationPriority.DEFAULT ＝ "default"
HIGH
AndroidNotificationPriority.HIGH ＝ "high"
LOW
AndroidNotificationPriority.LOW ＝ "low"
MAX
AndroidNotificationPriority.MAX ＝ "max"
MIN
AndroidNotificationPriority.MIN ＝ "min"
AndroidNotificationVisibility
AndroidNotificationVisibility Values

UNKNOWN
AndroidNotificationVisibility.UNKNOWN ＝ 0
PUBLIC
AndroidNotificationVisibility.PUBLIC ＝ 1
PRIVATE
AndroidNotificationVisibility.PRIVATE ＝ 2
SECRET
AndroidNotificationVisibility.SECRET ＝ 3
IosAlertStyle
IosAlertStyle Values

NONE
IosAlertStyle.NONE ＝ 0
BANNER
IosAlertStyle.BANNER ＝ 1
ALERT
IosAlertStyle.ALERT ＝ 2
IosAllowsPreviews
IosAllowsPreviews Values

NEVER
IosAllowsPreviews.NEVER ＝ 0
ALWAYS
IosAllowsPreviews.ALWAYS ＝ 1
WHEN_AUTHENTICATED
IosAllowsPreviews.WHEN_AUTHENTICATED ＝ 2
IosAuthorizationStatus
IosAuthorizationStatus Values

NOT_DETERMINED
IosAuthorizationStatus.NOT_DETERMINED ＝ 0
DENIED
IosAuthorizationStatus.DENIED ＝ 1
AUTHORIZED
IosAuthorizationStatus.AUTHORIZED ＝ 2
PROVISIONAL
IosAuthorizationStatus.PROVISIONAL ＝ 3
EPHEMERAL
IosAuthorizationStatus.EPHEMERAL ＝ 4
PermissionStatus
PermissionStatus Values

DENIED
PermissionStatus.DENIED ＝ "denied"
User has denied the permission.

GRANTED
PermissionStatus.GRANTED ＝ "granted"
User has granted the permission.

UNDETERMINED
PermissionStatus.UNDETERMINED ＝ "undetermined"
User hasn't granted or denied the permission yet.

Previous (Expo SDK)

Network

Next (Expo SDK)

Pedometer

Was this doc helpful?



Share your feedback

Ask a question on the forums about Notifications

View open bug reports for Notifications

Edit this page

Sign up for the Expo Newsletter

reader@email.com

Sign Up
Unsubscribe at any time. Read our privacy policy.

Features

Installation

Usage

Present the notification to the user

Handle push notifications with navigation

Configuration

Credentials

Android

iOS

App config

Configurable properties

Permissions

Android

RECEIVE_BOOT_COMPLETED

SCHEDULE_EXACT_ALARM

iOS

Notification events listeners

Background notifications

Additional information

Set custom notification sounds

Android push notification payload specification

Interpret the iOS permissions response

Manage notification categories (interactive notifications)

Platform specific guides

Handling notification channels 

Custom notification icon and colors 

API

Fetch tokens for push notifications

addPushTokenListener()
getDevicePushTokenAsync()
getExpoPushTokenAsync()
removePushTokenSubscription()
Listen to notification events

addNotificationReceivedListener()
addNotificationResponseReceivedListener()
addNotificationsDroppedListener()
getLastNotificationResponseAsync()
removeNotificationSubscription()
useLastNotificationResponse()
Handle incoming notifications when the app is in the foreground

setNotificationHandler()
Handle incoming notifications when the app is not in the foreground

registerTaskAsync()
unregisterTaskAsync()
Fetch information about notifications-related permissions

getPermissionsAsync()
requestPermissionsAsync()
Manage application badge icon

getBadgeCountAsync()
setBadgeCountAsync()
Schedule notifications

cancelAllScheduledNotificationsAsync()
cancelScheduledNotificationAsync()
getAllScheduledNotificationsAsync()
getNextTriggerDateAsync()
presentNotificationAsync()
scheduleNotificationAsync()
Dismiss notifications

dismissAllNotificationsAsync()
dismissNotificationAsync()
getPresentedNotificationsAsync()
Manage notification channels (Android-specific)

deleteNotificationChannelAsync()
deleteNotificationChannelGroupAsync()
getNotificationChannelAsync()
getNotificationChannelGroupAsync()
getNotificationChannelGroupsAsync()
getNotificationChannelsAsync()
setNotificationChannelAsync()
setNotificationChannelGroupAsync()
Manage notification categories (interactive notifications)

deleteNotificationCategoryAsync()
getNotificationCategoriesAsync()
setNotificationCategoryAsync()
Constants

DEFAULT_ACTION_IDENTIFIER
Methods

setAutoServerRegistrationEnabledAsync()
unregisterForNotificationsAsync()
Interfaces

AudioAttributes
BeaconRegion
CalendarNotificationTrigger
CircularRegion
DailyNotificationTrigger
DailyTriggerInput
ExpoPushToken
ExpoPushTokenOptions
FirebaseRemoteMessage
FirebaseRemoteMessageNotification
IosNotificationPermissionsRequest
LocationNotificationTrigger
NativeDevicePushToken
Notification
NotificationAction
NotificationBehavior
NotificationCategory
NotificationChannel
NotificationChannelGroup
NotificationChannelGroupInput
NotificationChannelGroupManager
NotificationChannelManager
NotificationHandler
NotificationPermissionsRequest
NotificationPermissionsStatus
NotificationRequest
NotificationRequestInput
NotificationResponse
PermissionResponse
Region
TimeIntervalNotificationTrigger
TimeIntervalTriggerInput
UnknownNotificationTrigger
WeeklyNotificationTrigger
WeeklyTriggerInput
YearlyNotificationTrigger
YearlyTriggerInput
Types

AudioAttributesInput
CalendarTriggerInput
CalendarTriggerInputValue
ChannelAwareTriggerInput
DateTriggerInput
DevicePushToken
ExplicitlySupportedDevicePushToken
ImplicitlySupportedDevicePushToken
NativeNotificationPermissionsRequest
NotificationCategoryOptions
NotificationChannelInput
NotificationContent
NotificationContentAndroid
NotificationContentAttachmentIos
NotificationContentInput
NotificationContentIos
NotificationHandlingError
NotificationTrigger
NotificationTriggerInput
PermissionExpiration
PermissionHookOptions
PushNotificationTrigger
PushTokenListener()
RequiredBy
SchedulableNotificationTriggerInput
Subscription
Enums

AndroidAudioContentType
AndroidAudioUsage
AndroidImportance
AndroidNotificationPriority
AndroidNotificationVisibility
IosAlertStyle
IosAllowsPreviews
IosAuthorizationStatus
PermissionStatus
 hacı bunu uygulayacağız seninle bak bu dökümantasyona göre. expo go da bildirim sistemi çalışıyor ancak build alıp google playe uygulamayı yüklediğimde oradaki versiyınunda uygulama çalışmıyor ne yapacağız nasıl yapacağız // App.js
import React, { useEffect } from 'react';
import Aptabase from "@aptabase/react-native";
import { NavigationContainer } from '@react-navigation/native';
import AppNavigator from './src/navigation/AppNavigator';
import { ThemeAndLanguageProvider, useThemeAndLanguage } from './src/utils/ThemeAndLanguageContext';
import { VocabularyProvider } from './src/screens/VocabularyContext'; 
import { LogBox,Linking } from 'react-native';
import StatusBarManager from './src/components/StatusBarManager'; 
import * as Notifications from 'expo-notifications';
import { db } from './src/utils/firebase';
import { doc, setDoc, deleteDoc } from 'firebase/firestore';
import AsyncStorage from '@react-native-async-storage/async-storage';
import { HeartProvider } from './src/screens/HeartContext';  // Yeni context dosyasını import et

// Initialize Firebase Analytics
Aptabase.init("A-EU-4450884874"); // Buraya kendi App Key'inizi yazın

// LogBox ile belirli uyarıları gizleme
LogBox.ignoreLogs(['Warning: A props object containing a "key" prop is being spread into JSX']);

// Expo push bildirim ayarları
Notifications.setNotificationHandler({
  handleNotification: async () => ({
    shouldShowAlert: true,
    shouldPlaySound: true,
    shouldSetBadge: false,
  }),
});

function AppContent() {
  const navigationRef = React.useRef();
  const notificationListener = React.useRef();
  const responseListener = React.useRef();
  const { locale } = useThemeAndLanguage();

  // Push token'ını alıp Firestore'a kaydetme fonksiyonu
  const getAndSaveNotificationToken = async () => {
    try {
      // Bildirim izinlerini alma
      const { status: existingStatus } = await Notifications.getPermissionsAsync();
      let finalStatus = existingStatus;
      
      // İzin verilmediyse iste
      if (existingStatus !== 'granted') {
        const { status } = await Notifications.requestPermissionsAsync();
        finalStatus = status;
      }

      console.log('Bildirim izni durumu:', finalStatus);

      if (finalStatus !== 'granted') {
        console.log('Bildirim izni alınamadı!');
        return;
      }

      // Expo push token'ını alma
      const tokenData = await Notifications.getExpoPushTokenAsync();
      const token = tokenData.data;
      console.log('Expo push token:', token);

      // Firebase Firestore'a token ve locale bilgilerini kaydetme
      await setDoc(doc(db, 'notificationTokens', token), { token, locale });
      console.log('Token Firestore\'a kaydedildi.');

      // Token'ı AsyncStorage'a kaydetme
      await AsyncStorage.setItem('notificationToken', token);
      console.log('Token AsyncStorage\'a kaydedildi.');

      return token;
    } catch (error) {
      console.error('Token alma ve kaydetme hatası:', error);
    }
  };

  // Locale değiştiğinde Firestore'daki locale bilgisini güncelleme fonksiyonu
  const updateNotificationLocale = async () => {
    try {
      const storedToken = await AsyncStorage.getItem('notificationToken');
      if (storedToken) {
        await setDoc(doc(db, 'notificationTokens', storedToken), { locale }, { merge: true });
        console.log('Locale bilgisi Firestore\'a güncellendi.');
      } else {
        console.log('Stored token bulunamadı, locale güncellenmedi.');
      }
    } catch (error) {
      console.error('Locale güncelleme hatası:', error);
    }
  };

  // Token'ın güncel olup olmadığını kontrol etme ve güncelleme fonksiyonu
  const checkAndUpdateToken = async () => {
    try {
      const storedToken = await AsyncStorage.getItem('notificationToken');
      const currentTokenData = await Notifications.getExpoPushTokenAsync();
      const currentToken = currentTokenData.data;

      console.log('Stored Token:', storedToken);
      console.log('Current Token:', currentToken);

      if (storedToken !== currentToken) {
        // Eski token'ı Firestore'dan silme
        if (storedToken) {
          await deleteDoc(doc(db, 'notificationTokens', storedToken));
          console.log('Eski token Firestore\'dan silindi.');
        }

        // Yeni token'ı Firestore'a kaydetme
        await setDoc(doc(db, 'notificationTokens', currentToken), { token: currentToken, locale });
        console.log('Yeni token Firestore\'a kaydedildi.');

        // Yeni token'ı AsyncStorage'a kaydetme
        await AsyncStorage.setItem('notificationToken', currentToken);
        console.log('Yeni token AsyncStorage\'a kaydedildi.');
      }
    } catch (error) {
      console.error('Token kontrol ve güncelleme hatası:', error);
    }
  };

  useEffect(() => {
    // Uygulama başlatıldığında token alma ve kaydetme
    getAndSaveNotificationToken().then(token => {
      if (token) {
        console.log('Push token alındı ve kaydedildi:', token);
      } else {
        console.log('Push token kaydedilmedi.');
      }
    });

    // Uygulama başlatma olayını Aptabase'e kaydetme
    Aptabase.trackEvent("app_started", { message: "Uygulama başlatıldı!" });

    // Her saat başı token'ı kontrol etme ve güncelleme
    const tokenCheckInterval = setInterval(checkAndUpdateToken, 1000 * 60 * 60); // Her saat

    // Bildirim alındığında yapılacak işlemler
    notificationListener.current = Notifications.addNotificationReceivedListener(notification => {
      console.log('Bildirim alındı:', notification);
    });

responseListener.current = Notifications.addNotificationResponseReceivedListener(response => {
  const data = response.notification.request.content.data;
  const type = data.type;

  if (type === 'update') {
    // Güncelleme bildirimi, Google Play'e yönlendir
    const playStoreUrl = data.url || "https://play.google.com/store/apps/details?id=com.ReadArabic.ReadArabic";
    Linking.openURL(playStoreUrl);
  } else if (data.storyId && navigationRef.current) {
    // Eğer story bildirimiyse, story ekranına yönlendir
    navigationRef.current.navigate('ReadStoryScreen', { storyId: data.storyId });
  }
});


    // Temizleme işlemleri
    return () => {
      Notifications.removeNotificationSubscription(notificationListener.current);
      Notifications.removeNotificationSubscription(responseListener.current);
      clearInterval(tokenCheckInterval);
    };
  }, []); // İlk render

  // Locale değiştiğinde Firestore'daki locale bilgisini güncelleme
  useEffect(() => {
    updateNotificationLocale();
  }, [locale]);

  return (
    <NavigationContainer ref={navigationRef}>
      <StatusBarManager /> 
      <AppNavigator />
    </NavigationContainer>
  );
}

export default function App() {
  return (
    <ThemeAndLanguageProvider>
      <VocabularyProvider>
        <HeartProvider>
          <AppContent />
        </HeartProvider>
      </VocabularyProvider>
    </ThemeAndLanguageProvider>
  );
}// app.config.js

export default ({ config }) => ({
  ...config,
  scheme: "myapp", // Unique scheme name
  android: {
    ...config.android,
    googleServicesFile: "./google-services.json", // Path to your Android Firebase config file
  },
  extra: {
    ...config.extra,
    apiKeyGoogle: process.env.API_KEY_GOOGLE,
    apiKey: process.env.FIREBASE_API_KEY,
    authDomain: process.env.FIREBASE_AUTH_DOMAIN,
    projectId: process.env.FIREBASE_PROJECT_ID,
    storageBucket: process.env.FIREBASE_STORAGE_BUCKET,
    messagingSenderId: process.env.FIREBASE_MESSAGING_SENDER_ID,
    appId: process.env.FIREBASE_APP_ID,
    apiKeyVoiceRSS: process.env.apiKeyVoiceRSS,
    type: process.env.FIREBASE_TYPE,
    private_key_id: process.env.FIREBASE_PRIVATE_KEY_ID,
    private_key: process.env.FIREBASE_PRIVATE_KEY,
    client_email: process.env.FIREBASE_CLIENT_EMAIL,
    client_id: process.env.FIREBASE_CLIENT_ID,
    auth_uri: process.env.FIREBASE_AUTH_URI,
    token_uri: process.env.FIREBASE_TOKEN_URI,
    auth_provider_x509_cert_url: process.env.FIREBASE_AUTH_PROVIDER_X509_CERT_URL,
    client_x509_cert_url: process.env.FIREBASE_CLIENT_X509_CERT_URL,
    universe_domain: process.env.FIREBASE_UNIVERSE_DOMAIN,
    WEB_CLIENT_ID: process.env.WEB_CLIENT_ID, // Ensure this is your actual Web Client ID
    scheme: "myapp", // Scheme should be the same as above
  },
});