Build a shared calendar system where teams create named calendars with member lists, and events are color-coded by calendar. A table_calendar Custom Widget displays events from all calendars the user belongs to, queried via Firestore arrayContains on memberIds. Events support attendee invitations with RSVP status tracking. When creating a new event, an overlap detection check warns users about scheduling conflicts. Each calendar has its own color, making it easy to distinguish work, personal, and team events at a glance.
Building a Shared Team Calendar in FlutterFlow
This tutorial creates a multi-user calendar similar to Google Calendar where users belong to multiple calendars and see all their events in one view. Each calendar has its own color and member list. Events can have attendees who accept or decline invitations. The system detects overlapping events to prevent scheduling conflicts. This pattern is used for team coordination, family scheduling, project management, and shared resource booking.
Prerequisites
- A FlutterFlow project with Firestore configured
- Basic understanding of Custom Widgets and subcollections in FlutterFlow
- Familiarity with the table_calendar Flutter package
- A Firebase project with test user accounts for multi-user testing
Step-by-step guide
Create the Firestore data model for calendars and events
Create the Firestore data model for calendars and events
Create a calendars collection with fields: name (String), ownerId (String), memberIds (String array containing user IDs), color (String, hex code like '#FF5733'). Create an events collection with fields: calendarId (String), title (String), startTime (Timestamp), endTime (Timestamp), location (String), description (String), createdBy (String), attendees (array of Maps with userId, displayName, and status: pending, accepted, declined), recurrence (String: none, daily, weekly, monthly). Add 2-3 calendars with different members and 5-10 events spread across them.
Expected result: Firestore has calendars with member lists and events with attendee tracking ready for display.
Build the calendar view with table_calendar Custom Widget
Build the calendar view with table_calendar Custom Widget
Create a CalendarPage. First, query the calendars collection where memberIds arrayContains the current user ID. Store the results in Page State userCalendars (Document List). For each calendar, query events where calendarId matches. Since Firestore arrayContains only supports one value per query, you must run separate queries per calendar and merge results client-side in a Custom Function. Create a Custom Widget wrapping the table_calendar package. Pass the merged events list to the widget. Each event marker dot on a calendar day uses the color from its parent calendar. Tap a day to show that day's events in a ListView below the calendar.
Expected result: A calendar widget shows color-coded event markers from all calendars the user belongs to.
Display daily events and create new events
Display daily events and create new events
Below the calendar widget, show a ListView of events for the selected day, each as a Container with a colored left border matching the calendar color, the event title, time range, location, and attendee count. Tap an event to navigate to an EventDetailPage. Add a floating action button to create new events. The creation form includes: calendar DropDown (from userCalendars), title TextField, start and end DateTimePickers, location TextField, description TextField, and an Add Attendees section where users search team members and add them to the attendees array with default status pending.
Expected result: Users see daily event details and can create new events with calendar selection and attendee invitations.
Implement attendee RSVP with accept and decline actions
Implement attendee RSVP with accept and decline actions
On the EventDetailPage, show the event details and an attendees section listing each attendee with their name and RSVP status as a colored badge (grey for pending, green for accepted, red for declined). If the current user is an attendee with pending status, display Accept and Decline buttons. On tap, update the attendees array on the event document: find the entry matching the current userId and change its status field. Use a Cloud Function or direct update. When someone RSVPs, optionally send a push notification to the event creator. Show a summary count: 3 accepted, 1 declined, 2 pending.
Expected result: Attendees can accept or decline event invitations, and the organizer sees RSVP status for all invitees.
Add overlap detection when creating or editing events
Add overlap detection when creating or editing events
When the user taps Save on the event creation form, before writing to Firestore, run an overlap check. Query events for the current user's calendars where startTime is less than the new event's endTime AND endTime is greater than the new event's startTime. This finds any events that overlap with the proposed time range. If overlapping events exist, show a dialog listing the conflicts with their titles and times, and ask the user to confirm or adjust the time. If no conflicts, save the event directly. This prevents accidental double-booking without blocking it entirely.
Expected result: Users see a warning with conflicting event details before saving an overlapping event.
Complete working example
1FIRESTORE DATA MODEL:2 calendars/{calendarId}3 name: String4 ownerId: String5 memberIds: [userId1, userId2, userId3]6 color: String (hex: "#FF5733")78 events/{eventId}9 calendarId: String10 title: String11 startTime: Timestamp12 endTime: Timestamp13 location: String14 description: String15 createdBy: String16 attendees: [17 { userId: "uid1", displayName: "Alice", status: "accepted" },18 { userId: "uid2", displayName: "Bob", status: "pending" }19 ]20 recurrence: String (none / daily / weekly / monthly)2122PAGE: CalendarPage23 Page State: userCalendars (List), selectedDay (DateTime), mergedEvents (List)2425 WIDGET TREE:26 Column27 ├── Row (calendar toggle chips: show/hide per calendar)28 ├── Custom Widget: TableCalendar29 │ events: mergedEvents (from all user calendars)30 │ markers: colored dots per calendar color31 │ onDaySelected: update selectedDay → filter events32 ├── Text ("Events for selectedDay")33 └── ListView (events for selected day)34 └── Container (colored left border = calendar color)35 Text (title)36 Text (startTime - endTime)37 Text (location)38 Row (attendee avatars + count)39 On Tap: navigate to EventDetailPage4041DATA FLOW (multi-calendar merge):42 1. Query calendars where memberIds arrayContains currentUser43 2. For EACH calendar: query events where calendarId == calendar.id44 3. Merge all event lists in Custom Function45 4. Pass merged list to TableCalendar widget46 (Firestore arrayContains only supports one value per query)4748PAGE: EventDetailPage49 Route Parameter: eventId50 Column51 ├── Text (title, startTime - endTime, location)52 ├── Text (description)53 ├── Section: Attendees54 │ ListView55 │ CircleImage + Text (name) + Badge (status: green/grey/red)56 │ Summary: "3 accepted, 1 declined, 2 pending"57 └── Row (Accept / Decline buttons, if currentUser is pending attendee)5859OVERLAP CHECK (on Save):60 conflicting = events.where(61 startTime < newEvent.endTime AND endTime > newEvent.startTime62 )63 if conflicting.isNotEmpty → show warning dialog64 else → save eventCommon mistakes when building a Multi-User Calendar with Shared Events in FlutterFlow
Why it's a problem: Querying events across all calendars in a single Firestore query
How to avoid: Query each calendar's events separately, then merge the results client-side in a Custom Function before passing to the calendar widget.
Why it's a problem: Updating a single attendee status by rewriting the entire attendees array
How to avoid: Use arrayRemove to remove the old attendee entry and arrayUnion to add the updated one, or use a Cloud Function that handles the update atomically.
Why it's a problem: Not assigning distinct colors to each calendar
How to avoid: Store a hex color on each calendar document and use it consistently for markers, event borders, and filter chips.
Best practices
- Query each calendar separately and merge events client-side for Firestore compatibility
- Color-code events by calendar using a hex color field on the calendar document
- Show attendee RSVP status with colored badges for quick visual scanning
- Run overlap detection before saving new events to warn about scheduling conflicts
- Allow users to toggle calendar visibility with filter chips above the calendar
- Store attendee status in the event document for efficient single-read access
- Use recurrence fields to support repeating events without duplicating documents
Still stuck?
Copy one of these prompts to get a personalized, step-by-step explanation.
I want to build a multi-user shared calendar in FlutterFlow using the table_calendar package. Users belong to multiple color-coded calendars, events have attendees with RSVP status, and the system detects overlapping events. Give me the Firestore data model, the multi-calendar query merge strategy, widget tree, and overlap detection logic.
Create a calendar page with a monthly calendar widget at the top showing colored event dots, a list of events for the selected day below with colored left borders, and a floating action button for creating new events with a calendar selector dropdown.
Frequently asked questions
How do I handle recurring events without duplicating documents?
Store the recurrence rule on the event document. In the Custom Widget, generate virtual instances of recurring events for the visible date range by applying the recurrence pattern to the original startTime. Only create separate documents when a user edits one instance of a recurring event.
Can I invite users who are not yet in the calendar?
Yes. Send an invitation via email or in-app notification. When the invitee accepts, add their userId to the calendar memberIds array. Until they accept, show them as a pending member.
How do I sync with Google Calendar?
Use the Google Calendar API via a Cloud Function. Set up OAuth2 for the user's Google account, then push and pull events between your Firestore events collection and Google Calendar. This requires the calendar.events scope.
Can I add reminders before events?
Yes. Add a reminders field on the event document with values like 10, 30, or 60 minutes before. A scheduled Cloud Function checks for upcoming events and sends push notifications at the specified intervals.
What if a team has more than 30 members?
Firestore arrayContains works with arrays of any size, but the memberIds array on the calendar document should stay under 1,000 items per Firestore document limits. For very large teams, consider a members subcollection instead.
Can RapidDev help build an enterprise calendar system?
Yes. RapidDev can build calendar systems with room and resource booking, availability conflict resolution, Google Calendar sync, recurring event management, and role-based calendar access.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation