Lesson 4: Local Notifications & Precision Scheduling
Now that we have established a solid foundation with permissions and channels, it's time to trigger our first real notifications. In this lesson, we move from theory to implementation by learning how to send immediate alerts and schedule future messages with surgical precision.
We will cover:
- The Notification Anatomy: Understanding the
contentandtriggerobjects. - Immediate Alerts: Triggering notifications for instant user feedback.
- Time Interval Triggers: Delaying alerts by specific durations.
- Calendar Triggers: Scheduling recurring or date-specific reminders.
- Handling Identifiers: Tracking and managing your scheduled tasks.
The Anatomy of an Expo Notification
To send an invitation, we use the scheduleNotificationAsync function. This function requires a single configuration object with two primary keys:
content: Defines what the user sees (Title, Body, Data, Sound).trigger: Defines when the user sees it (Now, in 5 minutes, or every Monday).
Think of the content as the letter inside an envelope, and the trigger as the delivery instructions written on the outside.
1. Immediate Alerts (The "Now" Trigger)
The simplest form of notification is one that fires immediately. This is often used for welcome messages or instant system feedback.
index.tstypescriptimport * as Notifications from 'expo-notifications'; const fireInstantNotification = async () => { await Notifications.scheduleNotificationAsync({ content: { title: "Welcome to NotifyMe! 👋", body: "Your journey to professional task management starts now.", data: { type: "welcome" }, channelId: "tasks", // Linking to our established channel }, trigger: null, // 'null' triggers the notification immediately }); };
2. Delaying Notifications (Time Intervals)
If you need to remind a user of a task in the near future (e.g., "Remind me in 10 minutes"), the TimeIntervalTrigger is your tool.
index.tstypescriptconst remindInFiveMinutes = async () => { await Notifications.scheduleNotificationAsync({ content: { title: "Task Reminder 📝", body: "Time to review your daily goals.", channelId: "tasks", }, trigger: { seconds: 5 * 60, // 5 minutes in seconds repeats: false, }, }); };
3. High-Precision Scheduling (Calendar Triggers)
For To-Do apps or scheduling systems, you often need alerts at specific times. The CalendarTrigger allows for complex, recurring schedules based on the user's local time.
Weekly Recurring Reminder
index.tstypescriptconst scheduleMondaySync = async () => { await Notifications.scheduleNotificationAsync({ content: { title: "Weekly Sync 🚀", body: "Set your objectives for the week ahead.", channelId: "default", }, trigger: { weekday: 2, // Monday (Sunday = 1, Monday = 2, ...) hour: 9, minute: 0, repeats: true, }, }); };
4. Managing Identifiers & The "Hidden" Metadata
Every time you schedule a notification, Expo returns a unique identifier. This string is the only way to cancel or update that specific notification later.
index.tstypescriptconst notificationId = await Notifications.scheduleNotificationAsync({ content: { title: "Delayed Alert" }, trigger: { seconds: 60 } }); console.log("Registered ID:", notificationId);
The data Property
The data field in the content object is one of the most powerful features. The user never sees this JSON object, but your application can read it when the notification is tapped. This is how you implement "Deep Linking"—e.g., sending the user directly to a specific project or chat room.
Practical Application
In your HomeScreen.tsx, you can now bind these functions to UI elements to see the results in real-time.
App.jstsx<Button title="Instant Test" onPress={fireInstantNotification} /> <Button title="Remind in 1 Minute" onPress={() => scheduleTimedNotification(60)} />
“[!TIP] When testing scheduled notifications, make sure to put your app in the background (by pressing the home button). By default, notifications might behave differently or be suppressed if the app is currently in the foreground.
Your Challenge
Implement a "Daily Reflection" reminder that triggers every evening at 8:00 PM. Pass a unique piece of data (e.g., { screen: 'Reflection' }) that we will use in the next lesson to navigate the user.