Amanda Cavallaro
GDE Firebase, AoG, ML
Developer Advocate @ Vonage
@amdcavallaro
Manuela Sakura Rommel
Flutter Developer, WTM Ambassador
@ManuSakuraRo
Create an Appointment Scheduler Using Firebase
#F3Prague
Puf’s Scheduling App
Firebase
Grow your app
Build better apps
Improve app quality
Firebase Databases Comparison
Realtime Database
Cloud Firestore
Functionalities of the app
Puf’s Schedule App
Tech Stack and Dependencies (Flutter)
Tech Stack and Dependencies (JS)
Steps:
Dashboard
Setup
Create Database
Import the JSON file
{
"myAppointments": {
"0": {
"date": "2023-29-01T09:00",
"userId": "1236abcd"
},
"new_activity_7kh3a3a3z": {
"date": "2023-29-01T08:50",
"userId": "_7kh3a3a3z"
},
"new_activity_etxen95x3": {
"date": "2023-29-01T08:40",
"userId": "_etxen95x3"
}
}
}
Add Database Rules
Who can access, how your indexes are built, and how the data is structured
Install Firebase
Install Firebase
// Install the Firebase tools with npm
// if you don't already have it installed by typing:
npm install -g firebase-tools�
// The login process will open your browser
for authentication.
firebase login
�
Log in To Firebase
Install Firebase Tools
Prepare Initialization for App
flutterfire
// Activate flutterfire CLI by typing:
dart pub global activate flutterfire_cli�
// To start configuration, type:
flutterfire configure
�
Configure Firebase for
Flutter
Activate Flutter Fire
flutterfire configure
/// Select firebase project
i Found X Firebase projects.
? Select a Firebase project to configure your Flutter application��/// Choose platforms you want to support
? Which platform should your configuration support?
Firebase Options
static const FirebaseOptions ios = FirebaseOptions(
apiKey: 'MYSECRETSTAYSMYSECRET',
appId: '1234567890987654345678765',
messagingSenderId: '888888888',
projectId: 'your-project-id',
databaseURL: 'https://your-project-id-default.europe-west1.firebasedatabase.app',
storageBucket: 'your-project-id.appspot.com',
iosBundleId: 'com.example.yourProjectId,
);
Initialize Firebase
Initialize Firebase in App
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
}
Initialize Firebase
�
// Initializes Firebase
firebase init
�
Initialize Firebase
Select Project Option
? Please select an option: Use an existing project
? Select a default Firebase project for this directory: f3-appointment (f3 appointment)
UI
User Interface
HTML, CSS and JavaScript
User Interface
Flutter
Initialize & add dependencies
mkdir appointment-scheduler && cd appointment-scheduler
npm init
npm install @vonage/server-sdk dotenv uuid express firebase-admin firebase-functions
Initialize Project and Install Dependencies
Add dependencies
/// Add the rest of the dependencies
flutter pub add firebase_core
flutter pub add firebase_core firebase_database
flutter_bloc envied uuid
flutterfire configure
flutter clean
flutter pub get
Update configuration
Add packages
Clean dependencies
Handle environment variables
Environment Variables
//.env
FIREBASE_DATABASE_URL=
VONAGE_API_KEY=
VONAGE_API_SECRET=
VONAGE_FROM_NUMBER=
Add data to database, check for availability
and send SMS with Vonage APIs
Book an Appointment
// Check Slot Availability
checkIfAvailable = async (slot) => {
let snapshot = await ref.orderByChild("date").once("value");
let available = true;
snapshot.forEach((data) => {
let dataval = data.val();
for (let key in dataval) {
let datapoint = dataval[key];
if (slot === datapoint) {
available = false;
}
}
});
return available;
};
Using Vonage Communication APIs
Save the code in case of cancellation!
SMS Confirmation
// Sends SMS to the User
vonage.messages.send(
new SMS(text, phone_number, "Puf Appointment Scheduler"),
(err, data) => {
if (err) {
console.error(err);
} else {
console.log(data.message_uuid);
}
}
);
Add the Appointment to the Database in JS
// Adds the slot to the database
addToDatabase = () => {
let code = uuidv4();
ref.child(code).set({
date: slot,
userId: code,
});
return code;
};
Initialize the project
And book your appointment!
Sparky books an appointment
Dash books an appointment as well!
Delete data from Database
Delete an Appointment
Ways of Deleting Data
/// Remove method
_ref.child(id).remove();
/// Set method
_ref.child(id).set(null);
/// Update method
_ref.update(updates);
/// Deleting multiple datapoints using update
Map<String, dynamic> pathsToDelete = {
'21c073e5-1699-44e8-a213-b4b836e664ad': null,
'919a4866-3526-4288-843d-fac7e752f3af': null,
};
await _appointmentsRef.update(pathsToDelete);
Cancel the Appointment in Flutter
// Removes the slot from the database
Future<void> removeSlotfromDB(String id) async {
await _ref.child(id).remove();
}
Cancel the Appointment in Flutter
Booked and kept my appointment!
Booked but cancelled my appointment!
Code Available on GitHub
Flutter
https://github.com/MaElaRo/f3_appointment_scheduler
Code Available on GitHub
JavaScript
https://github.com/Vonage-Community/blog-messages_api-node_firebase-appointment_scheduler
Amanda Cavallaro
GDE Firebase, AoG, ML
Developer Advocate @ Vonage
@amdcavallaro
Manuela Sakura Rommel
Flutter Developer, WTM Ambassador
@ManuSakuraRo
Thank You!
#F3Prague
Q1. Trivia
Can you create a Firebase project:
A - From the Command Line
B - From the Firebase dashboard webpage
C - Both options are correct
Trivia
Can you create a Firebase project:
A - From the Command Line
B - From the Firebase dashboard webpage
C - Both options are correct
Q2. Trivia
What Firebase database is best optimized for Flutter apps?
Realtime Database (right)
Cloud Firestore (wrong)
Trivia
Can you create a Firebase project:
A - From the Command Line
B - From the Firebase dashboard webpage
C - Both options are correct
Q3. Trivia
What is the default state management solution that comes with Flutter?
BLoC (wrong)
setState (right)
Q4. Trivia
What Firebase product allows email/password authentication in Flutter apps?
Firebase Auth (right)
Cloud Functions (wrong)
Q5. Trivia
What is the name of the widget that manages app navigation in Flutter?
Navigator (right)
Router (wrong)
Q6. Trivia
Is Firebase Crashlytics built-in to Flutter apps by default?
Yes (wrong)
No (right)
Q7. Trivia
Does Flutter have built-in support for Firebase Cloud Messaging?
Yes (right)
No (wrong)
Q8. Trivia
Can you use Cloud Firestore in Flutter without the cloud_firestore plugin?
Yes (wrong)
No (right)
Q9. Trivia
What is the Firebase product used for hosting Flutter web apps?
Firebase Hosting (right)
Cloud Storage (wrong)
Q10. Trivia
Is Flutter a cross-platform framework?
Yes (right)
No (wrong)
Colors & Fonts
Google Sans 104px
Google Sans 64px
Google Sans 40px
Google Sans 30px
Color
#4285f4
#34a853
#fbbc05
#ea4335
Typography
#202124
#FFA65C
#D65BAD
#2254AF
#2DC4C0
#F8F9FA
#D2E3FC
#CEEAD6
#FEEFC3
#FAD2CF
“Quote goes here.”
Firstname Lastname
Template Slides Below
Title Goes Here
Subheading goes here
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent ornare id tellus ut sodales. Etiam ac suscipit nisi. Nam tincidunt porttitor nulla, et porttitor ante. Praesent porta dapibus justo quis aliquet. Nunc porttitor arcu sed nunc hendrerit feugiat. Integer tincidunt sed sapien quis consectetur. Sed quam nunc, varius non lectus non, pretium gravida purus.
This is a Headline
This is a Subheading
Half slide subtitle goes here
Body copy for this slide goes here. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
This is a headline for a half slide
Subtitle of a segue slide goes here.
Headline for a segue slide goes here
Half slide subtitle goes here
Body copy for this slide goes here. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
This is a headline for a half slide
Send screenshot to back
Half slide subtitle goes here
Body copy for this slide goes here. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
This is a headline for a half slide
Use crop image tool to crop to a �circle shape. Send screenshot to back.
Half slide subtitle goes here
Body copy for this slide goes here. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
This is a headline for a half slide
Send screenshot to back
Full bleed photos are great
protected void onTryUpdate(int reason) throws RetryException {
// Do some awesome stuff
int foo = 15;
publishArtwork(new Artwork.Builder()
.title(photo.name)
.imageUri(Uri.parse(photo.image_url))
.viewIntent(new Intent(Intent.ACTION_VIEW,
Uri.parse(“http://500px.com/photo/" + photo.id)))
.build());
scheduleUpdate(System.currentTimeMillis() + ROTATE_TIME_MILLIS);
}
Code slides use Roboto Mono
Graphics & Icons
Device Library
Source: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis non erat sem
Proprietary + Confidential
Device Library
Source: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis non erat sem
Proprietary + Confidential
Device Library
Source: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis non erat sem
Proprietary + Confidential
Logo Library
Logos can be scaled to any size
Source: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis non erat sem
Proprietary + Confidential
Logo Library
Logos can be scaled to any size
Proprietary + Confidential
Shape Library
Chart Data Source Info
Source: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis non erat sem
End
Step
Step
Step
Proprietary + Confidential
Shape Library
Text
Text
Text
Text
Text
Text
Text
Text
Text
Text
Text
Text
Lorem Ipsum
Lorem Ipsum
Lorem Ipsum
Source: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis non erat sem
Proprietary + Confidential
Shape Library
Text
Text
Text
Text
Text
Text
Text
Text
Text
Text
75%
25%
Proprietary + Confidential
Shape Library
30%
60%
63,096
54,537
36,910
33,492
12,038
A
B
C
D
E
24% of women
55% of men
75%
25%
Source: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis non erat sem
Proprietary + Confidential
Shape Library
Text
Text
Text
Proprietary + Confidential
protected void onTryUpdate(int reason) throws RetryException {
// Do some awesome stuff
int foo = 15;
publishArtwork(new Artwork.Builder()
.title(photo.name)
.imageUri(Uri.parse(photo.image_url))
.viewIntent(new Intent(Intent.ACTION_VIEW,
Uri.parse(“http://500px.com/photo/" + photo.id)))
.build());
scheduleUpdate(System.currentTimeMillis() + ROTATE_TIME_MILLIS);
}
Code slides use Roboto Mono
Charts & Maps
Icon Library
Modify color of the country by clicking on the icon and select fill from the menu
Proprietary + Confidential
Icon Library
Modify color of the area by clicking on the icon and select fill from the menu
Lorem Ipsum
Lorem Ipsum
Lorem Ipsum
Lorem Ipsum
Proprietary + Confidential
Icon Library
Modify color of the country by clicking on the icon and select fill from the menu
Source: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis non erat sem
Proprietary + Confidential
Icon Library
Modify color of the state by clicking on the icon and select fill from the menu
Source: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis non erat sem
Proprietary + Confidential
Icon Library
Accessibility
Expand
Late
Credit card
Extension
Thumb Up
Remove
Verified
Q&A
Finance
Android
Turn in
Trash
Actions
Download
History
Store
List
Wallet
Announcement
Backup
Document
Favorite 1
Open
Home
Swap
Account
Ratio
Tag
Server
Favorite 2
Grade/rate
Lock
Language
Receipt
Add shopping
Chart
Bug
Event
Find Page
Page view
Basket
Time
Work
Source: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis non erat sem
Proprietary + Confidential
Icon Library
Alarm
Assessment
Sync
Exit App
Movie
Visibility
Trolley
Open
Location
Settings
Assignment
Check
Explore
Thumb Down
Today
Perm Media
People
search
Airplane
Signal
Photo
Play 1
Block
Send
Smartphone
Style
Walk
Bluetooth
WiFi
Upload
Play 2
Laptop
iPhone
Controls
Bike
Pie Chart
Money
Attachment
Video
Business
Chromebook
Security
Notification
Bus
Source: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis non erat sem
Proprietary + Confidential
Icon Library
Developer
Write
Cloud
Audio
Key
Desktop Mac
Watch
Person
Car
Devices
Quote
Folder
Web Page
Archive
Desktop PC
Flag
World
Boat
Software
Emotion
Mic
Call
Cut
headphones
Camera
Education
Train
Weather
Link
Movie
Chart
Paste
Keyboard
TV
MMS
Subway
Hotel
Laundry
Location History
Layers
Offer
Map
Bar
Pizza
Web
Source: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis non erat sem
Proprietary + Confidential
Icon Library
Cafe
Theatre
Gaming
Florist
Restaurant
Gas
Delivery
Hospital
Taxi
Radio
Stream
Source: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis non erat sem
Proprietary + Confidential
The title of the talk will go here.
Speaker Name
GDG New York
@twitterhandle
Subtitle of the talk will go here