Wat zijn Notificaties?
Notificaties zijn berichten die gebruikers ontvangen, zelfs als de app niet open is. Er zijn twee soorten:
Soorten notificaties:
- Lokale notificaties: Worden door de app zelf verstuurd (bijvoorbeeld een herinnering)
- Push notificaties: Worden verstuurd vanaf een server (bijvoorbeeld een nieuw bericht)
Use cases:
- Herinneringen (lokaal)
- Nieuwe berichten (push)
- Updates en nieuws (push)
- Alarm klok (lokaal)
- Timers en countdowns (lokaal)
Installatie
Installeer de Expo Notifications package:
npx expo install expo-notifications
Import
import * as Notifications from 'expo-notifications';
Notification Handler Configureren
Stel in hoe notificaties moeten worden getoond als de app open is:
import * as Notifications from 'expo-notifications';
// Configureer hoe notificaties worden getoond
Notifications.setNotificationHandler({
handleNotification: async () => ({
shouldShowAlert: true, // Toon de notificatie
shouldPlaySound: true, // Speel geluid af
shouldSetBadge: false, // Update badge nummer
}),
});
Permissies Aanvragen
Voor notificaties heb je permissie van de gebruiker nodig.
Permissie Vragen
import { useState, useEffect } from 'react';
import { View, Pressable, Text, Platform, StyleSheet } from 'react-native';
import * as Notifications from 'expo-notifications';
export default function App() {
const [permission, setPermission] = useState(null);
useEffect(() => {
requestPermission();
}, []);
const requestPermission = async () => {
const { status } = await Notifications.requestPermissionsAsync();
setPermission(status === 'granted');
if (status !== 'granted') {
alert('Notificatie permissie geweigerd!');
}
};
return (
<View style={styles.container}>
<Text>
Permissie: {permission ? '✅ Toegestaan' : '❌ Geweigerd'}
</Text>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
});
Let op: Op Android krijg je automatisch permissie, maar op iOS moet de gebruiker expliciet toestemming geven!
Lokale Notificaties
Lokale notificaties worden direct door je app verstuurd.
Direct Notificatie Versturen
import { View, Pressable, Text, StyleSheet } from 'react-native';
import * as Notifications from 'expo-notifications';
export default function App() {
const sendNotification = async () => {
await Notifications.scheduleNotificationAsync({
content: {
title: "Je hebt een bericht! 📬",
body: "Dit is een test notificatie",
data: { data: 'goes here' },
},
trigger: null, // null = verstuur direct
});
};
return (
<View style={styles.container}>
<Pressable style={styles.button} onPress={sendNotification}>
<Text style={styles.buttonText}>Verstuur Notificatie</Text>
</Pressable>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
padding: 20,
},
button: {
backgroundColor: '#007AFF',
padding: 15,
borderRadius: 8,
alignItems: 'center',
},
buttonText: {
color: 'white',
fontWeight: 'bold',
fontSize: 16,
},
});
Met Geluid en Acties
const sendAdvancedNotification = async () => {
await Notifications.scheduleNotificationAsync({
content: {
title: "Nieuwe Opdracht 📝",
body: "Je hebt een nieuwe taak ontvangen!",
sound: 'default',
badge: 1,
data: {
taskId: 123,
screen: 'TaskDetail'
},
},
trigger: null,
});
};
Notificaties Plannen
Plan notificaties voor later met een trigger.
Na X Seconden
const scheduleNotification = async () => {
await Notifications.scheduleNotificationAsync({
content: {
title: "Herinnering ⏰",
body: "5 seconden zijn verstreken!",
},
trigger: {
seconds: 5,
},
});
};
Dagelijkse Herinnering
const scheduleDailyNotification = async () => {
await Notifications.scheduleNotificationAsync({
content: {
title: "Dagelijkse Herinnering 🌅",
body: "Goedemorgen! Vergeet niet te oefenen.",
},
trigger: {
hour: 9,
minute: 0,
repeats: true,
},
});
};
Specifieke Datum
const scheduleForDate = async () => {
const trigger = new Date();
trigger.setMinutes(trigger.getMinutes() + 1); // Over 1 minuut
await Notifications.scheduleNotificationAsync({
content: {
title: "Geplande Notificatie 📅",
body: "Deze notificatie was gepland!",
},
trigger: trigger,
});
};
Wekelijkse Herinnering
const scheduleWeeklyNotification = async () => {
await Notifications.scheduleNotificationAsync({
content: {
title: "Wekelijkse Check-in 📊",
body: "Tijd om je voortgang te bekijken!",
},
trigger: {
weekday: 1, // Maandag (1 = maandag, 7 = zondag)
hour: 10,
minute: 0,
repeats: true,
},
});
};
Geplande Notificaties Annuleren
// Annuleer één notificatie
const notificationId = await Notifications.scheduleNotificationAsync({...});
await Notifications.cancelScheduledNotificationAsync(notificationId);
// Annuleer alle geplande notificaties
await Notifications.cancelAllScheduledNotificationsAsync();
Push Notificaties
Push notificaties worden verstuurd vanaf een server. Je hebt een Expo Push Token nodig.
Push Token Ophalen
import { useState, useEffect } from 'react';
import { View, Text, StyleSheet } from 'react-native';
import * as Notifications from 'expo-notifications';
import * as Device from 'expo-device';
export default function App() {
const [expoPushToken, setExpoPushToken] = useState('');
useEffect(() => {
registerForPushNotificationsAsync();
}, []);
const registerForPushNotificationsAsync = async () => {
let token;
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('Permissie voor notificaties geweigerd!');
return;
}
token = await Notifications.getExpoPushTokenAsync({
projectId: 'your-project-id',
});
setExpoPushToken(token.data);
console.log('Push Token:', token.data);
} else {
alert('Push notificaties werken alleen op echte apparaten!');
}
};
return (
<View style={styles.container}>
<Text style={styles.title}>Push Token:</Text>
<Text style={styles.token}>{expoPushToken}</Text>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 20,
justifyContent: 'center',
},
title: {
fontSize: 18,
fontWeight: 'bold',
marginBottom: 10,
},
token: {
fontSize: 12,
color: '#666',
},
});
Push Notificatie Testen
Test push notificaties met de Expo Push Tool:
Via Expo Push Tool:
- Ga naar https://expo.dev/notifications
- Plak je Expo Push Token
- Vul titel en bericht in
- Klik op "Send a Notification"
Push Notificatie Versturen vanaf Server
// Voorbeeld met Node.js
const sendPushNotification = async (expoPushToken) => {
const message = {
to: expoPushToken,
sound: 'default',
title: 'Nieuw Bericht!',
body: 'Je hebt een nieuw bericht ontvangen',
data: { someData: 'goes here' },
};
await fetch('https://exp.host/--/api/v2/push/send', {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify(message),
});
};
Notificaties Afhandelen
Reageer op notificaties als gebruikers erop klikken.
Notificatie Klik Afhandelen
import { useEffect, useRef } from 'react';
import { View, Text } from 'react-native';
import * as Notifications from 'expo-notifications';
export default function App() {
const notificationListener = useRef();
const responseListener = useRef();
useEffect(() => {
// Luister naar notificaties (app is open)
notificationListener.current =
Notifications.addNotificationReceivedListener(notification => {
console.log('Notificatie ontvangen:', notification);
});
// Luister naar notificatie klikken
responseListener.current =
Notifications.addNotificationResponseReceivedListener(response => {
console.log('Notificatie geklikt:', response);
// Haal data uit notificatie
const data = response.notification.request.content.data;
// Navigeer naar scherm
if (data.screen) {
// router.push(data.screen);
}
});
return () => {
Notifications.removeNotificationSubscription(
notificationListener.current
);
Notifications.removeNotificationSubscription(
responseListener.current
);
};
}, []);
return (
<View>
<Text>Wachten op notificaties...</Text>
</View>
);
}
Navigeren na Notificatie Klik
import { useRouter } from 'expo-router';
import * as Notifications from 'expo-notifications';
export default function App() {
const router = useRouter();
useEffect(() => {
const subscription =
Notifications.addNotificationResponseReceivedListener(response => {
const data = response.notification.request.content.data;
// Navigeer naar detail scherm
if (data.taskId) {
router.push(`/tasks/${data.taskId}`);
}
});
return () => subscription.remove();
}, []);
return <View>...</View>;
}
Badge Nummer Updaten
// Zet badge nummer
await Notifications.setBadgeCountAsync(5);
// Verhoog badge nummer
const currentBadge = await Notifications.getBadgeCountAsync();
await Notifications.setBadgeCountAsync(currentBadge + 1);
// Reset badge nummer
await Notifications.setBadgeCountAsync(0);
Volledig Voorbeeld - Herinnering App
import { useState, useEffect } from 'react';
import { View, TextInput, Pressable, Text, FlatList, StyleSheet } from 'react-native';
import * as Notifications from 'expo-notifications';
// Configureer notification handler
Notifications.setNotificationHandler({
handleNotification: async () => ({
shouldShowAlert: true,
shouldPlaySound: true,
shouldSetBadge: false,
}),
});
export default function ReminderApp() {
const [text, setText] = useState('');
const [reminders, setReminders] = useState([]);
useEffect(() => {
requestPermission();
}, []);
const requestPermission = async () => {
const { status } = await Notifications.requestPermissionsAsync();
if (status !== 'granted') {
alert('Notificatie permissie nodig!');
}
};
const addReminder = async () => {
if (!text.trim()) return;
// Plan notificatie over 5 seconden
const notificationId = await Notifications.scheduleNotificationAsync({
content: {
title: "Herinnering ⏰",
body: text,
data: { id: Date.now() },
},
trigger: {
seconds: 5,
},
});
// Voeg toe aan lijst
setReminders([
...reminders,
{ id: notificationId, text, time: 'Over 5 seconden' },
]);
setText('');
};
const deleteReminder = async (id) => {
// Annuleer notificatie
await Notifications.cancelScheduledNotificationAsync(id);
// Verwijder uit lijst
setReminders(reminders.filter(r => r.id !== id));
};
return (
<View style={styles.container}>
<Text style={styles.title}>Herinneringen</Text>
<View style={styles.inputContainer}>
<TextInput
style={styles.input}
placeholder="Nieuwe herinnering..."
value={text}
onChangeText={setText}
/>
<Pressable style={styles.addButton} onPress={addReminder}>
<Text style={styles.addButtonText}>+</Text>
</Pressable>
</View>
<FlatList
data={reminders}
keyExtractor={(item) => item.id}
renderItem={({ item }) => (
<View style={styles.reminderCard}>
<View style={styles.reminderInfo}>
<Text style={styles.reminderText}>{item.text}</Text>
<Text style={styles.timeText}>{item.time}</Text>
</View>
<Pressable onPress={() => deleteReminder(item.id)}>
<Text style={styles.deleteButton}>X</Text>
</Pressable>
</View>
)}
/>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 20,
backgroundColor: '#f5f5f5',
},
title: {
fontSize: 32,
fontWeight: 'bold',
marginBottom: 20,
},
inputContainer: {
flexDirection: 'row',
marginBottom: 20,
},
input: {
flex: 1,
borderWidth: 1,
borderColor: '#ddd',
padding: 12,
borderRadius: 8,
backgroundColor: 'white',
marginRight: 10,
},
addButton: {
backgroundColor: '#007AFF',
width: 50,
borderRadius: 8,
justifyContent: 'center',
alignItems: 'center',
},
addButtonText: {
color: 'white',
fontSize: 24,
fontWeight: 'bold',
},
reminderCard: {
flexDirection: 'row',
backgroundColor: 'white',
padding: 15,
borderRadius: 8,
marginBottom: 10,
alignItems: 'center',
},
reminderInfo: {
flex: 1,
},
reminderText: {
fontSize: 16,
marginBottom: 4,
},
timeText: {
fontSize: 12,
color: '#666',
},
deleteButton: {
color: 'red',
fontSize: 18,
fontWeight: 'bold',
padding: 5,
},
});
Samenvatting
Lokale Notificaties
Door app verstuurd
Push Notificaties
Via server verstuurd
Scheduling
Notificaties plannen
Handlers
Reageren op klikken
Je hebt nu geleerd:
- Permissies aanvragen voor notificaties
- Lokale notificaties direct versturen
- Notificaties plannen met triggers
- Push tokens ophalen voor remote notificaties
- Notificatie klikken afhandelen
- Complete herinnering app implementeren