Push notifications
A push notification is an alert generated by an application when the application is not open. For mobile apps there are two types of notifications:
- remote notifications are sent to the device from a server using the device push token
- local notifications are scheduled from within the app and send to the current device only
We will not cover setting up and sending remote push notifications in this course, but thanks to Expo Go we can try out local notifications!
Install a notifications
Install expo-notifications and expo-device.
npx expo install expo-notifications expo-device
Ask for permission
Before we can send any push notifications, we need to ask for permission.
Let's add a little utility for it: this will check if the user has granted push permission already and if not, requests it.
Starting Android 8.0, all notifications must be assigned to a channel. Also on Android 13, app users must opt-in to receive notifications via a permissions prompt that is automatically triggered by the operating system. This prompt will not appear until at least one notification channel is created which is why we need to register a channel for Android.
New file: utils/registerForPushNotificationsAsync.ts
import { Platform } from "react-native";
import * as Device from "expo-device";
import * as Notifications from "expo-notifications";
export async function registerForPushNotificationsAsync() {
if (Platform.OS === "android") {
await Notifications.setNotificationChannelAsync("default", {
name: "default",
importance: Notifications.AndroidImportance.DEFAULT,
vibrationPattern: [0, 250, 250, 250],
showBadge: false,
});
}
if (Device.isDevice) {
const { status: existingStatus } =
await Notifications.getPermissionsAsync();
if (existingStatus !== "granted") {
const { status } = await Notifications.requestPermissionsAsync();
return status;
} else {
return existingStatus;
}
} else {
return null;
}
}
Note that you can only ask for push permission once. Further calls to requestPermissionsAsync
will not do anything. If you accidentally reject push notification permission, you'll have to uninstall and re-install the app to get prompted again. Alternatively go to Settings -> Notifications -> Expo Go and manually toggle on the Notifications permission.
Now let's call this function and check if we have push permission.
Update: app/counter/index.tsx
@@ -1,9 +1,22 @@
-import { Text, View, StyleSheet } from "react-native";
+import { Text, View, StyleSheet, TouchableOpacity } from "react-native";
+import { theme } from "../../theme";
+import { registerForPushNotificationsAsync } from "../../utils/registerForPushNotificationsAsync";
export default function CounterScreen() {
+ const handleRequestPermission = async () => {
+ const result = await registerForPushNotificationsAsync();
+ console.log("Permission: ", result);
+ };
+
return (
<View style={styles.container}>
- <Text style={styles.text}>Counter</Text>
+ <TouchableOpacity
+ onPress={handleRequestPermission}
+ style={styles.button}
+ activeOpacity={0.8}
+ >
+ <Text style={styles.buttonText}>Request permission</Text>
+ </TouchableOpacity>
</View>
);
}
@@ -14,7 +27,15 @@ const styles = StyleSheet.create({
justifyContent: "center",
alignItems: "center",
},
- text: {
- fontSize: 24,
+ button: {
+ backgroundColor: theme.colorBlack,
+ padding: 12,
+ borderRadius: 6,
+ },
+ buttonText: {
+ color: "#fff",
+ fontWeight: "bold",
+ textTransform: "uppercase",
+ letterSpacing: 1,
},
});
Update this to notify us in 5 seconds. Refer to the docs for details on the various ways to schedule notifications.
Update: app/counter/index.tsx
@@ -1,21 +1,36 @@
-import { Text, View, StyleSheet, TouchableOpacity } from "react-native";
+import { Text, View, StyleSheet, TouchableOpacity, Alert } from "react-native";
import { theme } from "../../theme";
import { registerForPushNotificationsAsync } from "../../utils/registerForPushNotificationsAsync";
+import * as Notifications from "expo-notifications";
export default function CounterScreen() {
- const handleRequestPermission = async () => {
+ const scheduleNotification = async () => {
const result = await registerForPushNotificationsAsync();
- console.log("Permission: ", result);
+ if (result === "granted") {
+ await Notifications.scheduleNotificationAsync({
+ content: {
+ title: "I'm a notification from your app! 📨",
+ },
+ trigger: {
+ seconds: 5,
+ },
+ });
+ } else {
+ Alert.alert(
+ "Unable to schedule notification",
+ "Enable the notifications permission for Expo Go in settings",
+ );
+ }
};
return (
<View style={styles.container}>
<TouchableOpacity
- onPress={handleRequestPermission}
+ onPress={scheduleNotification}
style={styles.button}
activeOpacity={0.8}
>
- <Text style={styles.buttonText}>Request permission</Text>
+ <Text style={styles.buttonText}>Schedule notification</Text>
</TouchableOpacity>
</View>
);
Make sure you background the app. The notification will not appear in the notification tray when the app is foregrounded because foreground notifications are handled separately.
Checkpoint
Android | iOS |
---|---|