How to Build an Event Booking App with Flutter and Back4App - Tutorials (2024)

Introduction

In today's fast-paced world, managing events and bookings through mobile applications has become increasingly essential. An Event Booking App allows users to browse upcoming events, book tickets, select seats, and manage their bookings seamlessly. In this tutorial, you will learn how to create a complete Event Booking App using Flutter for the frontend and Back4App as the backend service.

By the end of this tutorial, you will have built a functional app that:

  • Displays a list of events with details.

  • Allows users to view event schedules and venue information.

  • Enables ticket booking with seat selection.

  • Processes payments securely (integration with a payment gateway).

  • Manages user profiles, including booking history and preferences.

Let's get started!

Prerequisites

To complete this tutorial, you will need:

  • Flutter SDK installed on your local machine. Follow the official Flutter installation guide.

  • Basic knowledge of Dart and Flutter. If you're new to Flutter, consider going through Flutter's introductory tutorial.

  • A Back4App account. Sign up for a free account at Back4App.

  • Back4App Flutter SDK integrated into your project. You can learn how to set it up by following the Back4App Flutter Guide.

  • A code editor like Visual Studio Code or Android Studio.

  • Node.js and npm installed for running Back4App cloud functions. Install them from the official Node.js website.

Step 1 – Setting Up the Back4App Backend

In this step, you will set up your Back4App project, create the necessary classes (tables), and configure the backend to store event data, ticket information, and user profiles.

1.1. Create a New Back4App Application

  1. Log in to your Back4App account.

  2. Click on "Create new App".

  3. Enter an App Name (e.g., "EventBookingApp") and select your App Icon.

  4. Click "Create".

1.2. Configure Application Keys

  1. Navigate to your app's Dashboard.

  2. Click on "App Settings" > "Security & Keys".

  3. Note down the Application ID and Client Key. You will need these to initialize the Parse SDK in your Flutter app.

1.3. Define the Data Models

You need to create the following classes in Back4App:

  • Event: Stores event details.

  • Venue: Stores venue information.

  • Ticket: Manages ticket availability and bookings.

  • User: Manages user profiles (default class).

Create the Event Class

  1. In the left sidebar, click on "Database" to open the Data Browser.

  2. Click on "Create a class".

  3. Select "Custom", enter "Event" as the class name, and click "Create class".

  4. Add the following columns to the Event class:

    • name (String)

    • description (String)

    • date (Date)

    • image (File)

    • venue (Pointer to Venue)

    • price (Number)

Create the Venue Class

  1. Repeat the steps to create a new class named "Venue".

  2. Add the following columns:

    • name (String)

    • address (String)

    • capacity (Number)

    • seatingChart (File)

Create the Ticket Class

  1. Create a new class named "Ticket".

  2. Add the following columns:

    • event (Pointer to Event)

    • user (Pointer to User)

    • seatNumber (String)

    • price (Number)

    • isBooked (Boolean)

1.4. Enable User Authentication

  1. In the left sidebar, click on "Server Settings" > "General Settings".

  2. Under "Authentication", ensure that "Enable Class Level Permissions" is checked.

  3. Configure the User class permissions to allow users to sign up and log in.

1.5. Set Up Cloud Functions (Optional for Payment Processing)

For payment integration, you might need to write cloud functions. This step will depend on the payment gateway you choose (e.g., Stripe, PayPal). Refer to Back4App's documentation on Cloud Code Functions.

Step 2 – Initializing the Flutter Project

In this step, you will set up the Flutter project and integrate the Back4App Parse SDK.

2.1. Create a New Flutter Project

Open your terminal and run:

Text

1flutter create event_booking_app



Navigate to the project directory:

2.2. Add Dependencies

Open pubspec.yaml and add the following dependencies:

YAML

1dependencies:2 flutter:3 sdk: flutter4 cupertino_icons: ^1.0.25 parse_server_sdk_flutter: ^4.0.16 provider: ^6.0.07 # Add any additional packages you need, e.g., http, image_picker, etc.



Run flutter pub get to install the packages.

2.3. Initialize Parse SDK

In lib/main.dart, import the necessary packages and initialize Parse:

Dart

1import 'package:flutter/material.dart';2import 'package:parse_server_sdk_flutter/parse_server_sdk.dart';34void main() async {5 WidgetsFlutterBinding.ensureInitialized();67 const keyApplicationId = 'YOUR_BACK4APP_APPLICATION_ID';8 const keyClientKey = 'YOUR_BACK4APP_CLIENT_KEY';9 const keyParseServerUrl = 'https://parseapi.back4app.com';1011 await Parse().initialize(12 keyApplicationId,13 keyParseServerUrl,14 clientKey: keyClientKey,15 debug: true,16 autoSendSessionId: true,17 );1819 runApp(MyApp());20}2122class MyApp extends StatelessWidget {23 // Build your app's UI here24}



Replace 'YOUR_BACK4APP_APPLICATION_ID' and 'YOUR_BACK4APP_CLIENT_KEY' with your actual keys from Back4App.

Step 3 – Implementing User Authentication

Users need to sign up and log in to book events and manage their profiles.

3.1. Create Authentication Screens

Create two new Dart files in lib/:

  • login_screen.dart

  • signup_screen.dart

login_screen.dart

Dart

1import 'package:flutter/material.dart';2import 'package:parse_server_sdk_flutter/parse_server_sdk.dart';34class LoginScreen extends StatefulWidget {5 @override6 _LoginScreenState createState() => _LoginScreenState();7}89class _LoginScreenState extends State<LoginScreen> {10 final TextEditingController usernameController = TextEditingController();11 final TextEditingController passwordController = TextEditingController();1213 void doUserLogin() async {14 final username = usernameController.text.trim();15 final password = passwordController.text.trim();1617 final user = ParseUser(username, password, null);18 var response = await user.login();1920 if (response.success) {21 // Navigate to Home Screen22 Navigator.pushReplacementNamed(context, '/home');23 } else {24 // Show error message25 _showError(response.error!.message);26 }27 }2829 void _showError(String message) {30 // Implement a method to show error messages31 }3233 @override34 Widget build(BuildContext context) {35 // Build your login UI here36 }37}



signup_screen.dart

Dart

1import 'package:flutter/material.dart';2import 'package:parse_server_sdk_flutter/parse_server_sdk.dart';34class SignUpScreen extends StatefulWidget {5 @override6 _SignUpScreenState createState() => _SignUpScreenState();7}89class _SignUpScreenState extends State<SignUpScreen> {10 final TextEditingController usernameController = TextEditingController();11 final TextEditingController passwordController = TextEditingController();1213 void doUserRegistration() async {14 final username = usernameController.text.trim();15 final password = passwordController.text.trim();1617 final user = ParseUser(username, password, null);18 var response = await user.signUp();1920 if (response.success) {21 // Navigate to Home Screen22 Navigator.pushReplacementNamed(context, '/home');23 } else {24 // Show error message25 _showError(response.error!.message);26 }27 }2829 void _showError(String message) {30 // Implement a method to show error messages31 }3233 @override34 Widget build(BuildContext context) {35 // Build your sign-up UI here36 }37}



3.2. Update main.dart with Routes

Dart

1class MyApp extends StatelessWidget {2 @override3 Widget build(BuildContext context) {4 return MaterialApp(5 title: 'Event Booking App',6 initialRoute: '/login',7 routes: {8 '/login': (context) => LoginScreen(),9 '/signup': (context) => SignUpScreen(),10 '/home': (context) => HomeScreen(),11 // Add other routes as needed12 },13 );14 }15}



3.3. Implement Home Screen

Create a home_screen.dart file where authenticated users are redirected.

Dart

1import 'package:flutter/material.dart';23class HomeScreen extends StatelessWidget {4 @override5 Widget build(BuildContext context) {6 // Build your home screen UI here7 }8}



Step 4 – Displaying Events

Fetch events from Back4App and display them in a list.

4.1. Create Event Model

Create a Dart class event.dart in lib/models/.

Dart

1import 'package:parse_server_sdk_flutter/parse_server_sdk.dart';23class Event extends ParseObject implements ParseCloneable {4 Event() : super(_keyTableName);5 Event.clone() : this();67 static const String _keyTableName = 'Event';8 static const String keyName = 'name';9 static const String keyDescription = 'description';10 static const String keyDate = 'date';11 static const String keyImage = 'image';12 static const String keyVenue = 'venue';13 static const String keyPrice = 'price';1415 @override16 clone(Map<String, dynamic> map) => Event.clone()..fromJson(map);1718 String? get name => get<String>(keyName);19 String? get description => get<String>(keyDescription);20 DateTime? get date => get<DateTime>(keyDate);21 ParseFileBase? get image => get<ParseFileBase>(keyImage);22 ParseObject? get venue => get<ParseObject>(keyVenue);23 double? get price => get<double>(keyPrice);24}



4.2. Fetch Events in Home Screen

In home_screen.dart, fetch events and display them.

Dart

1import 'package:flutter/material.dart';2import 'models/event.dart';3import 'package:parse_server_sdk_flutter/parse_server_sdk.dart';45class HomeScreen extends StatefulWidget {6 @override7 _HomeScreenState createState() => _HomeScreenState();8}910class _HomeScreenState extends State<HomeScreen> {11 Future<List<Event>> getEvents() async {12 QueryBuilder<Event> queryEvents = QueryBuilder<Event>(Event())13 ..orderByDescending('date');14 final ParseResponse apiResponse = await queryEvents.query();1516 if (apiResponse.success && apiResponse.results != null) {17 return apiResponse.results as List<Event>;18 } else {19 return [];20 }21 }2223 @override24 Widget build(BuildContext context) {25 return Scaffold(26 appBar: AppBar(27 title: Text('Events'),28 ),29 body: FutureBuilder<List<Event>>(30 future: getEvents(),31 builder: (context, snapshot) {32 if (snapshot.hasData) {33 List<Event> events = snapshot.data!;34 return ListView.builder(35 itemCount: events.length,36 itemBuilder: (context, index) {37 Event event = events[index];38 return ListTile(39 title: Text(event.name ?? 'No Title'),40 subtitle: Text(event.date?.toLocal().toString() ?? ''),41 onTap: () {42 // Navigate to Event Details43 Navigator.push(44 context,45 MaterialPageRoute(46 builder: (context) => EventDetailsScreen(event: event),47 ),48 );49 },50 );51 },52 );53 } else if (snapshot.hasError) {54 return Center(child: Text('Error loading events'));55 } else {56 return Center(child: CircularProgressIndicator());57 }58 },59 ),60 );61 }62}



4.3. Create Event Details Screen

Create event_details_screen.dart.

Dart

1import 'package:flutter/material.dart';2import 'models/event.dart';34class EventDetailsScreen extends StatelessWidget {5 final Event event;67 EventDetailsScreen({required this.event});89 void _bookTicket(BuildContext context) {10 // Implement ticket booking logic11 Navigator.push(12 context,13 MaterialPageRoute(14 builder: (context) => SeatSelectionScreen(event: event),15 ),16 );17 }1819 @override20 Widget build(BuildContext context) {21 // Build UI to display event details22 return Scaffold(23 appBar: AppBar(24 title: Text(event.name ?? 'Event Details'),25 ),26 body: Column(27 children: [28 // Display event image, description, date, venue, etc.29 Text(event.description ?? ''),30 ElevatedButton(31 onPressed: () => _bookTicket(context),32 child: Text('Book Ticket'),33 ),34 ],35 ),36 );37 }38}



Step 5 – Implementing Seat Selection

Allow users to select seats before booking.

5.1. Create Seat Selection Screen

Create seat_selection_screen.dart.

Dart

1import 'package:flutter/material.dart';2import 'models/event.dart';34class SeatSelectionScreen extends StatelessWidget {5 final Event event;67 SeatSelectionScreen({required this.event});89 // Mock data for seats10 final List<String> seats = List.generate(100, (index) => 'Seat ${index + 1}');1112 @override13 Widget build(BuildContext context) {14 // Build UI for seat selection15 return Scaffold(16 appBar: AppBar(17 title: Text('Select Seats'),18 ),19 body: GridView.builder(20 gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(21 crossAxisCount: 5,22 ),23 itemCount: seats.length,24 itemBuilder: (context, index) {25 String seat = seats[index];26 return GestureDetector(27 onTap: () {28 // Handle seat selection29 // Navigate to Payment Screen30 Navigator.push(31 context,32 MaterialPageRoute(33 builder: (context) => PaymentScreen(event: event, seat: seat),34 ),35 );36 },37 child: Card(38 child: Center(child: Text(seat)),39 ),40 );41 },42 ),43 );44 }45}



Step 6 – Processing Payments

Integrate a payment gateway to process ticket payments securely.

6.1. Choose a Payment Gateway

For this tutorial, we will assume the use of Stripe.

6.2. Set Up Stripe Account and Obtain API Keys

  1. Sign up for a Stripe account.

  2. Obtain your Publishable Key and Secret Key.

6.3. Add Stripe Dependency

Add stripe_payment package to your pubspec.yaml:

YAML

1dependencies:2 stripe_payment: ^1.0.9



Run flutter pub get.

6.4. Implement Payment Screen

Create payment_screen.dart.

Dart

1import 'package:flutter/material.dart';2import 'package:stripe_payment/stripe_payment.dart';3import 'models/event.dart';45class PaymentScreen extends StatefulWidget {6 final Event event;7 final String seat;89 PaymentScreen({required this.event, required this.seat});1011 @override12 _PaymentScreenState createState() => _PaymentScreenState();13}1415class _PaymentScreenState extends State<PaymentScreen> {16 void initState() {17 super.initState();18 StripePayment.setOptions(19 StripeOptions(20 publishableKey: 'YOUR_STRIPE_PUBLISHABLE_KEY',21 // Optionally set other options22 ),23 );24 }2526 void _startPayment() async {27 // Implement payment logic28 // Create Payment Method29 PaymentMethod paymentMethod = await StripePayment.paymentRequestWithCardForm(30 CardFormPaymentRequest(),31 );3233 // Process the payment using a cloud function or your server34 // For simplicity, we'll assume payment is successful3536 _saveTicket();37 }3839 void _saveTicket() async {40 // Save ticket information to Back4App41 final ticket = ParseObject('Ticket')42 ..set('event', widget.event)43 ..set('user', await ParseUser.currentUser())44 ..set('seatNumber', widget.seat)45 ..set('price', widget.event.price)46 ..set('isBooked', true);4748 await ticket.save();4950 // Navigate to confirmation screen or display success message51 }5253 @override54 Widget build(BuildContext context) {55 // Build payment UI56 return Scaffold(57 appBar: AppBar(58 title: Text('Payment'),59 ),60 body: Center(61 child: ElevatedButton(62 onPressed: _startPayment,63 child: Text('Pay \$${widget.event.price}'),64 ),65 ),66 );67 }68}



Note: Payment processing requires secure handling of sensitive data. In a production app, you should process payments securely using your own server or cloud functions.

Step 7 – Managing User Profiles

Allow users to view and manage their bookings and preferences.

7.1. Create Profile Screen

Create profile_screen.dart.

Dart

1import 'package:flutter/material.dart';2import 'package:parse_server_sdk_flutter/parse_server_sdk.dart';34class ProfileScreen extends StatelessWidget {5 Future<List<ParseObject>> getUserTickets() async {6 final user = await ParseUser.currentUser();7 QueryBuilder<ParseObject> queryTickets = QueryBuilder<ParseObject>(ParseObject('Ticket'))8 ..whereEqualTo('user', user)9 ..includeObject(['event']);1011 final ParseResponse apiResponse = await queryTickets.query();1213 if (apiResponse.success && apiResponse.results != null) {14 return apiResponse.results as List<ParseObject>;15 } else {16 return [];17 }18 }1920 @override21 Widget build(BuildContext context) {22 // Build profile UI23 return Scaffold(24 appBar: AppBar(25 title: Text('My Profile'),26 ),27 body: FutureBuilder<List<ParseObject>>(28 future: getUserTickets(),29 builder: (context, snapshot) {30 if (snapshot.hasData) {31 List<ParseObject> tickets = snapshot.data!;32 return ListView.builder(33 itemCount: tickets.length,34 itemBuilder: (context, index) {35 ParseObject ticket = tickets[index];36 ParseObject event = ticket.get('event');37 return ListTile(38 title: Text(event.get<String>('name') ?? 'No Event Name'),39 subtitle: Text('Seat: ${ticket.get<String>('seatNumber')}'),40 );41 },42 );43 } else if (snapshot.hasError) {44 return Center(child: Text('Error loading tickets'));45 } else {46 return Center(child: CircularProgressIndicator());47 }48 },49 ),50 );51 }52}



7.2. Add Navigation to Profile Screen

In your home_screen.dart or main navigation drawer, add a link to the Profile Screen.

Dart

1IconButton(2 icon: Icon(Icons.person),3 onPressed: () {4 Navigator.push(5 context,6 MaterialPageRoute(builder: (context) => ProfileScreen()),7 );8 },9),



Step 8 – Testing the App

Run your app using:

Text

1flutter run



Test the following functionalities:

  • Sign up and log in.

  • View the list of events.

  • View event details.

  • Select seats and proceed to payment.

  • Process a payment (test mode if possible).

  • View bookings in the profile.

Conclusion

Congratulations! You have built a complete Event Booking App using Flutter and Back4App. This app allows users to browse events, book tickets with seat selection, process payments, and manage their profiles and bookings.

From here, you can enhance your app by:

  • Adding push notifications for event reminders.

  • Implementing search and filtering for events.

  • Enhancing the UI/UX with better design and animations.

  • Securing payment processing with server-side validation.

For more information on Flutter and Back4App features, check out:

By integrating Flutter with Back4App, you leverage a powerful combination to build scalable, feature-rich mobile applications efficiently.

How to Build an Event Booking App with Flutter and Back4App - Tutorials (2024)

References

Top Articles
Latest Posts
Recommended Articles
Article information

Author: Sen. Emmett Berge

Last Updated:

Views: 5745

Rating: 5 / 5 (60 voted)

Reviews: 83% of readers found this page helpful

Author information

Name: Sen. Emmett Berge

Birthday: 1993-06-17

Address: 787 Elvis Divide, Port Brice, OH 24507-6802

Phone: +9779049645255

Job: Senior Healthcare Specialist

Hobby: Cycling, Model building, Kitesurfing, Origami, Lapidary, Dance, Basketball

Introduction: My name is Sen. Emmett Berge, I am a funny, vast, charming, courageous, enthusiastic, jolly, famous person who loves writing and wants to share my knowledge and understanding with you.