Schedule push notifications in FlutterFlow using one of three methods: Cloud Scheduler with a Cloud Function for recurring system notifications, Firestore document writes that trigger a background Cloud Function at a future time, or user-configured reminders built with a DateTimePicker and stored in Firestore. Never create one Cloud Scheduler job per notification — you will hit Google's 500-job limit.
Three Ways to Schedule Push Notifications in FlutterFlow
FlutterFlow's built-in Push Notification action sends messages immediately, but scheduling a notification for a future time requires Cloud infrastructure. There are three approaches that suit different use cases. Cloud Scheduler works best for recurring system notifications that apply to all users (daily digests, weekly summaries). Firestore-triggered Cloud Functions work best for per-user notifications at a specific datetime (booking reminders, event alerts). User-configured reminders stored in Firestore with a scheduled check work best for habit or productivity apps where users set their own times. This tutorial covers all three approaches so you can choose the right tool for your specific notification type.
Prerequisites
- FlutterFlow project connected to Firebase with push notifications already configured
- Firebase Cloud Functions deployed (requires the Blaze pay-as-you-go plan)
- Firebase Cloud Messaging (FCM) set up with APNs certificates for iOS
- Basic understanding of FlutterFlow Action Flows and Firestore document writes
Step-by-step guide
Set up Cloud Scheduler for recurring system notifications
Set up Cloud Scheduler for recurring system notifications
Cloud Scheduler is Google Cloud's managed cron service. It sends an HTTP request to your Cloud Function on a schedule. In the Google Cloud Console (console.cloud.google.com), navigate to Cloud Scheduler and click Create Job. Set the frequency using cron syntax — for example, 0 9 * * * sends the notification at 9am every day. Set the target to HTTP, enter your Cloud Function's URL, set the method to POST, and add a body with any notification parameters. In your Cloud Function, call the Firebase Admin SDK's messaging().send() method to dispatch the notification to all subscribed users or a specific topic. Use FCM topics for broadcasting to all users: subscribe users to a topic on app launch using messaging().subscribeToTopic().
1// Cloud Function: sendDailyDigest2// Triggered by Cloud Scheduler at 0 9 * * *3const functions = require('firebase-functions');4const admin = require('firebase-admin');56exports.sendDailyDigest = functions.https.onRequest(async (req, res) => {7 const message = {8 notification: {9 title: 'Your Daily Digest',10 body: 'Here is what happened while you were away.',11 },12 topic: 'daily_digest', // all users subscribed to this topic13 };1415 await admin.messaging().send(message);16 res.status(200).send('Notification sent');17});Expected result: At 9am every day, Cloud Scheduler calls your Cloud Function which sends a push notification to all subscribed users.
Schedule per-user notifications using a Firestore scheduled_notifications collection
Schedule per-user notifications using a Firestore scheduled_notifications collection
For notifications at a specific user-defined time (booking reminder, event alert), write a document to a scheduled_notifications Firestore collection when the user schedules the notification. The document should contain: userId (String), fcmToken (String — the user's current FCM token), title (String), body (String), scheduledFor (Timestamp), sent (Boolean, default false). Create a Cloud Function using functions.pubsub.schedule('every 1 minutes') that queries scheduled_notifications where scheduledFor is less than or equal to now AND sent is false. For each matching document, send the notification via admin.messaging().send() and update sent to true. This polling approach scales to thousands of per-user notifications without hitting Cloud Scheduler limits.
1// Cloud Function: checkScheduledNotifications2// Runs every minute via Pub/Sub schedule3const functions = require('firebase-functions');4const admin = require('firebase-admin');56exports.checkScheduledNotifications = functions.pubsub7 .schedule('every 1 minutes')8 .onRun(async (context) => {9 const now = admin.firestore.Timestamp.now();10 const db = admin.firestore();1112 const due = await db13 .collection('scheduled_notifications')14 .where('scheduledFor', '<=', now)15 .where('sent', '==', false)16 .limit(100)17 .get();1819 const batch = db.batch();20 const sends = [];2122 due.docs.forEach((doc) => {23 const data = doc.data();24 sends.push(25 admin.messaging().send({26 token: data.fcmToken,27 notification: { title: data.title, body: data.body },28 })29 );30 batch.update(doc.ref, { sent: true });31 });3233 await Promise.all(sends);34 await batch.commit();35 return null;36 });Expected result: Any notification document where scheduledFor has passed and sent is false gets dispatched within 1 minute of the scheduled time.
Build the user-facing reminder UI with DateTimePicker
Build the user-facing reminder UI with DateTimePicker
In FlutterFlow, create a reminder settings page or bottom sheet. Add a DateTimePicker widget (found under Form widgets) that lets the user pick a future date and time. Add a DropdownButton widget for repeat interval with options: Once, Daily, Weekly, Monthly. Add a Text input for the reminder label. Connect a Save button with an Action Flow that: (1) validates the selected time is in the future, (2) fetches the user's current FCM token using a Custom Action, (3) creates a Firestore document in scheduled_notifications with all the fields including scheduledFor set to the DateTimePicker value. For repeat notifications, also store repeatInterval and the Cloud Function handles rescheduling by writing a new document with the next occurrence time after sending.
Expected result: The reminder settings UI lets users pick a date, time, and repeat interval. Saving creates a Firestore document that the Cloud Function will process.
Handle FCM token refresh to keep scheduled notifications deliverable
Handle FCM token refresh to keep scheduled notifications deliverable
FCM tokens change when a user reinstalls the app, clears app data, or the token is rotated by Firebase. If you store a stale token in a scheduled_notifications document, the notification will silently fail to deliver. In FlutterFlow, add an On App Launch action that calls a Custom Action to refresh the FCM token and update the token field in the user's Firestore document. When the Cloud Function sends a notification and receives a messaging/invalid-registration-token error, delete the corresponding scheduled_notifications document and log the failure so the user can reschedule. This keeps your scheduled_notifications collection clean and delivery rates high.
Expected result: The app automatically keeps the stored FCM token current so that scheduled notifications can be delivered even after token rotation.
Complete working example
1// Cloud Function: checkScheduledNotifications2// Deploy with: firebase deploy --only functions:checkScheduledNotifications3// Requires firebase-admin and firebase-functions packages45const functions = require('firebase-functions');6const admin = require('firebase-admin');78// Initialize if not already initialized9if (!admin.apps.length) admin.initializeApp();1011exports.checkScheduledNotifications = functions.pubsub12 .schedule('every 1 minutes')13 .timeZone('UTC')14 .onRun(async (context) => {15 const now = admin.firestore.Timestamp.now();16 const db = admin.firestore();1718 // Fetch due notifications (not yet sent)19 const snapshot = await db20 .collection('scheduled_notifications')21 .where('scheduledFor', '<=', now)22 .where('sent', '==', false)23 .limit(100)24 .get();2526 if (snapshot.empty) return null;2728 const batch = db.batch();29 const messagePromises = [];3031 for (const doc of snapshot.docs) {32 const data = doc.data();3334 // Send the notification35 messagePromises.push(36 admin.messaging().send({37 token: data.fcmToken,38 notification: {39 title: data.title || 'Reminder',40 body: data.body || '',41 },42 android: { priority: 'high' },43 apns: { payload: { aps: { sound: 'default' } } },44 }).catch((err) => {45 console.error(`Failed to send to ${doc.id}:`, err.message);46 })47 );4849 // Mark as sent50 batch.update(doc.ref, { sent: true, sentAt: now });5152 // Reschedule if repeating53 if (data.repeatInterval && data.repeatInterval !== 'once') {54 const next = calculateNextOccurrence(data.scheduledFor.toDate(), data.repeatInterval);55 const newRef = db.collection('scheduled_notifications').doc();56 batch.set(newRef, {57 ...data,58 scheduledFor: admin.firestore.Timestamp.fromDate(next),59 sent: false,60 createdAt: now,61 });62 }63 }6465 await Promise.all(messagePromises);66 await batch.commit();67 return null;68 });6970function calculateNextOccurrence(date, interval) {71 const next = new Date(date);72 if (interval === 'daily') next.setDate(next.getDate() + 1);73 else if (interval === 'weekly') next.setDate(next.getDate() + 7);74 else if (interval === 'monthly') next.setMonth(next.getMonth() + 1);75 return next;76}Common mistakes when scheduling Push Notifications in FlutterFlow
Why it's a problem: Creating one Cloud Scheduler job per notification
How to avoid: Use the polling Cloud Function approach — store all scheduled notifications in Firestore and run a single Cloud Function every minute that queries for due documents. One Cloud Scheduler job supports unlimited per-user notifications.
Why it's a problem: Storing the FCM token at reminder-creation time and never updating it
How to avoid: Always fetch the user's current FCM token from their Firestore user document at send time in the Cloud Function, rather than using the token stored with the scheduled notification document.
Why it's a problem: Scheduling notifications in the user's local time without accounting for timezone
How to avoid: Store the user's IANA timezone string in their Firestore user document and use a timezone library in your Cloud Function to convert the scheduled time to UTC before comparison.
Best practices
- Use a single polling Cloud Function for all per-user notifications — never one Cloud Scheduler job per notification
- Always fetch the user's latest FCM token from Firestore at send time rather than the token stored with the notification
- Store the user's IANA timezone string and convert all scheduled times to UTC in your Cloud Function
- Set a sent field on notification documents and mark them immediately on dispatch to prevent double-delivery
- Add a TTL or manual cleanup for sent notification documents older than 30 days to keep the collection lean
- Use FCM topics for broadcast notifications (daily digests) to avoid querying all user tokens
- Test scheduled notifications with a time 1-2 minutes in the future during development — never wait hours for a cron test
Still stuck?
Copy one of these prompts to get a personalized, step-by-step explanation.
I am building a reminder app in FlutterFlow with Firebase. Users set reminder times with a DateTimePicker. I want to send push notifications at the scheduled times. How do I write a Firebase Cloud Function that runs every minute, queries a Firestore scheduled_notifications collection for due documents, sends FCM notifications, and marks them as sent?
Create a FlutterFlow Action Flow for a Save Reminder button. It should: validate the DateTimePicker value is in the future, call a Custom Action to get the current user's FCM token, then create a Firestore document in the scheduled_notifications collection with fields: userId, fcmToken, title (from a TextField), scheduledFor (from the DateTimePicker), repeatInterval (from a Dropdown), and sent set to false.
Frequently asked questions
Can FlutterFlow schedule push notifications without a Cloud Function?
No. FlutterFlow's built-in Push Notification action sends immediately. Scheduling for a future time always requires a server-side component — either a Cloud Function triggered by Cloud Scheduler or a polling function. There is no client-side way to schedule a future push notification reliably, because the app may not be running when the time arrives.
How accurate is the every-1-minute polling approach for scheduled notifications?
Cloud Functions triggered by Pub/Sub schedule can have up to 2-3 minutes of jitter in practice. For most reminder apps this is acceptable. If you need sub-minute precision (e.g., real-time financial alerts), use a different approach such as Firestore's realtime listeners on a server process or a dedicated notification service like OneSignal.
Does the Blaze (pay-as-you-go) Firebase plan cost a lot to run a polling Cloud Function every minute?
No. A Cloud Function that runs for 1-2 seconds every minute uses approximately 1,440 invocations per day. Firebase Cloud Functions include 2 million free invocations per month and 400,000 GB-seconds of compute time. A simple polling function for a small app will stay within the free tier for most use cases.
Can I cancel a scheduled notification after it has been saved in Firestore?
Yes. Because scheduled notifications are stored as Firestore documents, cancelling one is as simple as deleting or updating the document. Add a delete action to your reminder detail page that removes the scheduled_notifications document by its ID. The Cloud Function will no longer find and send it.
How do I send scheduled notifications to all users at once, like a weekly newsletter?
Use Cloud Scheduler with an FCM topic for broadcast notifications. Subscribe all users to a topic (e.g., 'weekly_digest') when they sign in. Create one Cloud Scheduler job that calls a Cloud Function on your desired schedule, and the function sends a single message to the topic. Firebase FCM handles delivery to all subscribed devices automatically.
What happens if the user has disabled push notifications on their device?
FCM will return a messaging/registration-token-not-registered or messaging/invalid-registration-token error when attempting delivery to a device where notifications are disabled. Your Cloud Function should catch this error and either delete the scheduled document or update a status field to 'failed' so you can surface the issue in your admin dashboard.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation