Search code examples
javascripttypescriptreact-nativeexpoexpo-notifications

TypeError: Notifications.getPermissionsAsync is not a function. Expo Notifications


I'm trying to send push notifications using expo-notifications. I'm using the example in the documentation and it works very well with javascript. When I try it in typescript it gives me the error:

[Unhandled promise rejection: TypeError: Notifications.getPermissionsAsync is not a function. (In 'Notifications.getPermissionsAsync()', 'Notifications.getPermissionsAsync' is undefined)]

Here is my code

import { StatusBar } from "expo-status-bar";
import { Button, StyleSheet, Text, View, Platform } from "react-native";
import * as Device from "expo-device";
import * as Notifications from "expo-notifications";
import { useEffect, useState } from "react";

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

const sendPushNotification = async (expoPushToken: any) => {
  const message = {
    to: expoPushToken,
    sound: "default",
    title: "Test title",
    body: "Test body",
    data: { testData: "test data" },
  };

  await fetch("https://exp.host/--/api/v2/push/send", {
    method: "POST",
    headers: {
      Accept: "application/json",
      "Accept-encoding": "gzip, deflate",
      "Content-Type": "application/json",
    },
    body: JSON.stringify(message),
  });
};
export default function App() {
  const [token, setToken] = useState();

  console.log({ token });

  useEffect(() => {
    let mounted = true;
    if (mounted) {
      (async () => {
        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;
          }
          const { data } = await Notifications.getExpoPushTokenAsync();
          setToken(data as any);
        } else {
          alert("Must use physical device for Push Notifications");
        }

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

    return () => {
      mounted = false;
    };
  }, []);
  return (
    <View style={styles.container}>
      <Text>Open up App.js to start working on your app!</Text>
      {token && (
        <Button onPress={() => sendPushNotification(token)} title="Send" />
      )}
      <StatusBar style="auto" />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "#fff",
    alignItems: "center",
    justifyContent: "center",
  },
});

So what may be possibly the problem, because it seems like everything is fine when i'm using javascript.


Solution

  • The issue might be with the typings for the expo notifications module. Ensure that you have the latest version of the library installed, and if the issue still persists, try importing it as:

    import Notifications from 'expo-notifications/src/Notifications'
    

    instead of:

    import * as Notifications from 'expo-notifications'