SlideShare a Scribd company logo
FlutterNinjas 2024
Exploring Full-Stack Dart for Firebase
Server-Side Development
Kosuke (@kosukesaigusa)
Hello, Flutter Ninjas!
FlutterNinjas 2024
kosukesaigusa 1
About me
Kosuke Saigusa (@kosukesaigusa)
Application Engineer located in Japan
Flutter, Dart Lover
OSS & Community Contributor
pub.dev
geoflutterfire_plus
flutterfire_gen
...
Hold & Speak at Tech Conferences in Japan
FlutterNinjas 2024
kosukesaigusa 2
Explore Full-Stack Dart
FlutterNinjas 2024
kosukesaigusa 3
Goal
Exploring Full-Stack Dart for Firebase Server-Side
Development
Develop server-side processes for Firebase using Dart
Integration of various GCP services
Implement solutions with pub.dev packages:
functions_framework
dart_firebase_admin
FlutterNinjas 2024
kosukesaigusa 4
First Demo
Let's see sample app!
FlutterNinjas 2024
kosukesaigusa 5
Overview
FlutterNinjas 2024
kosukesaigusa 6
Cloud Run
FlutterNinjas 2024
kosukesaigusa 7
Cloud Run
FlutterNinjas 2024
Cloud Run is a managed compute
platform that lets you run
containers directly on top of
Google's scalable infrastructure.
You can deploy code written in any
programming language on Cloud
Run if you can build a container
image from it.
“
“
kosukesaigusa 8
Compile Dart Program to Executable
bin/hello.dart
void main(List<String> arguments) {
print('Hello, Flutter Ninjas!');
}
Compile to executable:
dart compile exe bin/hello.dart -o bin/hello
Run:
$ ./bin/hello
Hello, Flutter Ninjas!
FlutterNinjas 2024
kosukesaigusa 9
functions_framework package
FlutterNinjas 2024
kosukesaigusa 10
functions_framework package
Developed by GoogleCloudPlatform organization
Provides a framework to write Dart functions and deploy it on Cloud
Run, GAE, ...etc
FlutterNinjas 2024
kosukesaigusa 11
Write HTTP Function in Dart
Write function with @CloudFunction in bin/functions.dart :
import 'package:functions_framework/functions_framework.dart';
import 'package:shelf/shelf.dart';
@CloudFunction()
Response hello(Request request) => Response.ok('Hello, Flutter Ninjas!');
Generate code:
dart pub run build_runner build -d
FlutterNinjas 2024
kosukesaigusa 12
Generated code bin/server.dart :
import 'package:functions_framework/serve.dart';
import 'package:hello_server/functions.dart' as function_library;
Future<void> main(List<String> args) async {
await serve(args, _nameToFunctionTarget);
}
FunctionTarget? _nameToFunctionTarget(String name) => switch (name) {
'hello' => FunctionTarget.http(function_library.hello),
_ => null
};
FlutterNinjas 2024
kosukesaigusa 13
Launch server:
$ dart run bin/server.dart
Listening on :8080
Request to server:
$ curl http://localhost:8080
Hello, Flutter Ninjas!
FlutterNinjas 2024
kosukesaigusa 14
Run in Container
Dockerfile
FROM dart:stable AS build
WORKDIR /app
COPY . .
RUN dart pub get
RUN dart pub run build_runner build -d
RUN dart compile exe bin/server.dart -o bin/server
FROM scratch
COPY --from=build /runtime/ /
COPY --from=build /app/bin/server /app/bin/
EXPOSE 8080
ENTRYPOINT ["/app/bin/server", "--target=hello", "--signature-type=http"]
FlutterNinjas 2024
kosukesaigusa 15
Build container:
docker build -t hello .
Run it:
$ docker run -it -p 8080:8080 --name app hello
Listening on :8080
Request to server:
$ curl http://localhost:8080
Hello, Flutter Ninjas!
FlutterNinjas 2024
kosukesaigusa 16
Demo
Try to run hello function on local machine!
FlutterNinjas 2024
kosukesaigusa 17
Deploy HTTP Function on Cloud Run
Deploy on Cloud Run with Dockerfile using gcloud CLI:
gcloud run deploy hello  # Function (service) name
--source=.  # Path to Dockerfile
--platform=managed  # For Cloud Run
--allow-unauthenticated # For public access
Request to Cloud Run:
$ curl https://hello-<generated-url>-an.a.run.app
Hello, Flutter Ninjas!
Be careful of unauthenticated functions.
FlutterNinjas 2024
kosukesaigusa 18
FlutterNinjas 2024
kosukesaigusa 19
Demo
Deploy hello function to Cloud Run!
FlutterNinjas 2024
kosukesaigusa 20
FlutterNinjas 2024
kosukesaigusa 21
dart_firebase_admin package
FlutterNinjas 2024
kosukesaigusa 22
dart_firebase_admin package
Developed by invertase organization
Remi is the main contributor
FlutterNinjas 2024
kosukesaigusa 23
dart_firebase_admin package
final adminApp = FirebaseAdminApp.initializeApp(
'your-project-id',
Credential.fromServiceAccountParams(
clientId: 'your-client-id',
privateKey: 'your-private-key',
email: 'your-email',
),
);
final firestore = Firestore(adminApp);
final auth = Auth(adminApp);
final messaging = Messaging(adminApp);
FlutterNinjas 2024
kosukesaigusa 24
Example: Send Cloud Messaging
Future<void> main async {
final messaging = Messaging(adminApp);
await messaging.send(
TokenMessage(
token: 'some-fcm-token',
notification: Notification(
title: 'FlutterNinjas 2024!',
body: 'Welcome to FlutterNinjas!',
),
),
);
}
FlutterNinjas 2024
kosukesaigusa 25
Demo
Send FCM to mobile app from local admin SDK!
FlutterNinjas 2024
kosukesaigusa 26
dart_firebase_admin package
FlutterNinjas 2024
kosukesaigusa 27
Transfer Cloud Firestore event to Cloud Run
FlutterNinjas 2024
kosukesaigusa 28
Eventarc
FlutterNinjas 2024
Eventarc lets you build event-
driven architectures without
having to implement, customize, or
maintain the underlying
infrastructure. Eventarc offers a
standardized solution to manage
the flow of state changes, called
events, between decoupled
microservices.
“
“
kosukesaigusa 29
CloudEvents
FlutterNinjas 2024
CloudEvents is a specification for
describing event data in a common
way.
CloudEvents seeks to dramatically
simplify event declaration and
delivery across services, platforms,
and beyond!
“
“
kosukesaigusa 30
Write CloudEvents triggered Function in Dart
FlutterNinjas 2024
kosukesaigusa 31
Write CloudEvents triggered Function in Dart
Define function with @CloudFunction() , and give two parameters:
CloudEvent event
RequestContext context
@CloudFunction()
void oncreateevent(CloudEvent event, RequestContext context)
=> Response.ok('Hello, Flutter Ninjas!');
Only lowercase letters, numbers and '-' are allowed for function
name.
FlutterNinjas 2024
kosukesaigusa 32
Deploy CloudEvents triggered Function on Cloud Run
Set --signature-type=cloudevent to ENTRYPOINT option:
FROM dart:stable AS build
WORKDIR /app
COPY . .
RUN dart pub get
RUN dart pub run build_runner build -d
RUN dart compile exe bin/server.dart -o bin/server
FROM scratch
COPY --from=build /runtime/ /
COPY --from=build /app/bin/server /app/bin/
EXPOSE 8080
ENTRYPOINT ["/app/bin/server", "--target=oncreateevent", "--signature-type=cloudevent"]
FlutterNinjas 2024
kosukesaigusa 33
Deploy Eventarc trigger
Deploy Eventarc trigger using gcloud CLI
Transfer:
from Cloud Firestore: type=google.cloud.firestore.document.v1.created
to Cloud Run: oncreateevent
gcloud eventarc triggers create oncreateevent  # Trigger name
--destination-run-service=oncreateevent  # Destination function name
--event-filters="type=google.cloud.firestore.document.v1.created"  # Event type
--event-filters="database=(default)" 
--event-filters="namespace=(default)" 
--event-filters-path-pattern="document=events/{eventId}"  # Target path
--event-data-content-type="application/protobuf" 
--service-account="your-service-account-name@project-id.iam.gserviceaccount.com"
FlutterNinjas 2024
kosukesaigusa 34
FlutterNinjas 2024
kosukesaigusa 35
Demo
Deploy Eventarc trigger!
FlutterNinjas 2024
kosukesaigusa 36
FlutterNinjas 2024
kosukesaigusa 37
How to handle Raw CloudEvents data?
Request body is in application/protobuf byte data format:
[10, 195, 3, 10, 84, 112, 114, 111, 106, 101, 99, 116, 115, 47, 102, 117 ...]
FlutterNinjas 2024
kosukesaigusa 38
How to handle Raw CloudEvents data?
CloudEvents metadata found in header such as:
Triggered document
Triggered event type
{
"ce-dataschema": "https://github.com/googleapis/.../events/cloud/firestore/v1/data.proto",
"authorization": "Bearer ...",
"ce-subject": "documents/todos/6iGrCr5nJar6NNB8gPog",
"ce-source": "//firestore.googleapis.com/.../databases/(default)",
"ce-type": "google.cloud.firestore.document.v1.created", // Triggered event type
"content-type": "application/protobuf",
"ce-document": "todos/6iGrCr5nJar6NNB8gPog", // Triggered document
"ce-project": "...",
...
}
FlutterNinjas 2024
kosukesaigusa 39
firebase-functions (Node.js)
Node.js SDK provides:
Document path parameters from context.params.documentId
Triggered DocumentSnapshot snapshot
import * as functions from 'firebase-functions'
const onCreateTodo = functions
.region(`asia-northeast1`)
.firestore.document(`todos/{todoId}`)
.onCreate(async (snapshot, context) => {
const todoId = context.params.todoId
const data = snapshot.data()
const title = data.title
// ...
})
FlutterNinjas 2024
kosukesaigusa 40
Possible to write in Dart?
FlutterNinjas 2024
kosukesaigusa 41
dart_firebase_functions package
Still in early stages
Provides Node.js-like Firebase functions capability in Dart!
FlutterNinjas 2024
kosukesaigusa 42
onCreate
@OnDocumentCreated('todos/{todoId}')
Future<void> oncreatetodo(
({String todoId}) params,
QueryDocumentSnapshot snapshot,
RequestContext context,
) async {
final todoId = params.todoId;
final data = snapshot.data();
final title = data?['title'];
// ...
}
const onCreateTodo = functions
.region(`asia-northeast1`)
.firestore.document(`todos/{todoId}`)
.onCreate(async (snapshot, context) => {
const todoId = context.params.todoId
const data = snapshot.data()
const title = data.title
// ...
})
FlutterNinjas 2024
kosukesaigusa 43
onUpdate
@OnDocumentUpdated('todos/{todoId}')
Future<void> onupdatetodo(
({String todoId}) params,
({
QueryDocumentSnapshot before,
QueryDocumentSnapshot after,
}) snapshot,
RequestContext context,
) async {
final todoId = params.todoId;
final before = snapshot.before.data();
final after = snapshot.after.data();
final newTitle = after.title;
// ...
}
const onUpdateTodo = functions
.region(`asia-northeast1`)
.firestore.document(`todos/{todoId}`)
.onUpdate(async (snapshot, context) => {
const todoId = context.params.todoId
const before = snapshot.before.data()
const after = snapshot.after.data()
const newTitle = after.title
// ...
})
FlutterNinjas 2024
kosukesaigusa 44
onDelete
@OnDocumentDeleted('todos/{todoId}')
Future<void> ondeletetodo(
({String todoId}) params,
QueryDocumentSnapshot snapshot,
RequestContext context,
) async {
final todoId = params.todoId;
final data = snapshot.data();
final title = data?.title;
// ...
}
const onDeleteTodo = functions
.region(`asia-northeast1`)
.firestore.document(`todos/{todoId}`)
.onUpdate(async (snapshot, context) => {
const todoId = context.params.todoId
const data = snapshot.data()
const title = data.title
// ...
})
FlutterNinjas 2024
kosukesaigusa 45
onWrite
@OnDocumentUpdated('todos/{todoId}')
Future<void> onwritetodo(
({String todoId}) params,
({
QueryDocumentSnapshot before,
QueryDocumentSnapshot after,
}) snapshot,
RequestContext context,
) async {
final todoId = params.todoId;
final before = snapshot.before.data();
final after = snapshot.after.data();
final newTitle = after.title;
// ...
}
const onWriteTodo = functions
.region(`asia-northeast1`)
.firestore.document(`todos/{todoId}`)
.onWrite(async (snapshot, context) => {
const todoId = context.params.todoId
const before = snapshot.before.data()
const after = snapshot.after.data()
const newTitle = after?.title
// ...
})
FlutterNinjas 2024
kosukesaigusa 46
Nested Collection
@OnDocumentCreated('foos/{fooId}/bars/{barId}')
Future<void> oncreatebar(
({String fooId, String barId}) params,
QueryDocumentSnapshot snapshot,
RequestContext context,
) async {
final fooId = params.fooId;
final barId = params.barId;
final data = snapshot.data();
// ...
}
FlutterNinjas 2024
kosukesaigusa 47
Write Firestore triggered function in Dart:
@OnDocumentCreated('todos/{todoId}')
Future<void> oncreatetodo(
({String todoId}) params,
QueryDocumentSnapshot snapshot,
RequestContext context,
) async {
// Use Dart Firebase Admin SDK here.
}
Generate code:
dart pub run build_runner build -d
FlutterNinjas 2024
kosukesaigusa 48
Deploy it on Cloud Run
Set --signature-type=cloudevent to ENTRYPOINT option:
FROM dart:stable AS build
WORKDIR /app
COPY . .
RUN dart pub get
RUN dart pub run build_runner build -d
RUN dart compile exe bin/server.dart -o bin/server
FROM scratch
COPY --from=build /runtime/ /
COPY --from=build /app/bin/server /app/bin/
EXPOSE 8080
ENTRYPOINT ["/app/bin/server", "--target=oncreateevent", "--signature-type=cloudevent"]
FlutterNinjas 2024
kosukesaigusa 49
Final Demo
Let's see sample app's server-side code!
FlutterNinjas 2024
kosukesaigusa 50
Summary
In container, Dart executable can be run (Cloud Run)
HTTP and CloudEvents triggered functions are available in Dart,
thanks to functions_framework package
Firebase Admin SDK is available, thanks to dart_firebase_admin
package
Eventarc transfers CloudEvents from Cloud Firestore to Cloud Run
dart_firebase_function package provides Node.js-like Firebase
functions capability in Dart
FlutterNinjas 2024
kosukesaigusa 51
Explore Full-Stack Dart
FlutterNinjas 2024
kosukesaigusa 52
Thank you
FlutterNinjas 2024
kosukesaigusa 53

More Related Content

PDF
19-03-22.pdf
PPTX
Flutter festival gdsc juet guna
PPTX
Firebase integration with Flutter
PPTX
GoogleDSC_ GHRCE_ flutter_firebase.pptx
PDF
Firestore MENA digital days : GDG Abu dhabi
PDF
Flutter Festival IIT Goa: Session IV
PPTX
Flutter Leap of Faith
PPTX
Flutter festival ppt
19-03-22.pdf
Flutter festival gdsc juet guna
Firebase integration with Flutter
GoogleDSC_ GHRCE_ flutter_firebase.pptx
Firestore MENA digital days : GDG Abu dhabi
Flutter Festival IIT Goa: Session IV
Flutter Leap of Faith
Flutter festival ppt

Similar to FlutterNinjas 2024: Exploring Full-Stack Dart for Firebase Server-Side Development (20)

PDF
Flutter and Firebase – A Helpful Blend for Your Business App
PDF
Use Firebase to Host Your Flutter App on the Web
PPTX
Firebase .pptx
PDF
Cloud Messaging Flutter
PDF
10 03-2022
PPTX
2025 Flutter Study Group #3: State Management using Gemini and Vertex AI
PDF
Technologies Used by Adequate Infsoft for Mobile App Development.pdf
PDF
Flutter.pdf
PDF
Flutter (1).pdf
PDF
Fun with Flutter
PDF
How to develop a Flutter app.pdf
PDF
Developing Cross platform apps in flutter (Android, iOS, Web)
PDF
ML Kit , Cloud FF GDSC MESCOE.pdf
PPTX
All a flutter about Flutter.io
PPTX
Introductory session flutter festival
PPTX
Flutter Forward Event .pptx
PDF
A Journey to Continuous Delivery with Flutter ⚡️🚀🙂 (@Flutter_Connect 2025)
PPTX
Application Programming and continuing.pptx
PDF
Developing cross platform apps in Flutter (Android, iOS, and Web)
PDF
[ABC2018Spring]Flutterアプリ開発入門
Flutter and Firebase – A Helpful Blend for Your Business App
Use Firebase to Host Your Flutter App on the Web
Firebase .pptx
Cloud Messaging Flutter
10 03-2022
2025 Flutter Study Group #3: State Management using Gemini and Vertex AI
Technologies Used by Adequate Infsoft for Mobile App Development.pdf
Flutter.pdf
Flutter (1).pdf
Fun with Flutter
How to develop a Flutter app.pdf
Developing Cross platform apps in flutter (Android, iOS, Web)
ML Kit , Cloud FF GDSC MESCOE.pdf
All a flutter about Flutter.io
Introductory session flutter festival
Flutter Forward Event .pptx
A Journey to Continuous Delivery with Flutter ⚡️🚀🙂 (@Flutter_Connect 2025)
Application Programming and continuing.pptx
Developing cross platform apps in Flutter (Android, iOS, and Web)
[ABC2018Spring]Flutterアプリ開発入門
Ad

Recently uploaded (20)

PPTX
FINAL REVIEW FOR COPD DIANOSIS FOR PULMONARY DISEASE.pptx
PPTX
OOP with Java - Java Introduction (Basics)
PDF
BMEC211 - INTRODUCTION TO MECHATRONICS-1.pdf
PPTX
Lecture Notes Electrical Wiring System Components
PPTX
UNIT-1 - COAL BASED THERMAL POWER PLANTS
PDF
Mohammad Mahdi Farshadian CV - Prospective PhD Student 2026
PPT
Mechanical Engineering MATERIALS Selection
PPTX
UNIT 4 Total Quality Management .pptx
PPTX
MCN 401 KTU-2019-PPE KITS-MODULE 2.pptx
PPTX
CARTOGRAPHY AND GEOINFORMATION VISUALIZATION chapter1 NPTE (2).pptx
DOCX
ASol_English-Language-Literature-Set-1-27-02-2023-converted.docx
PDF
Evaluating the Democratization of the Turkish Armed Forces from a Normative P...
PDF
Automation-in-Manufacturing-Chapter-Introduction.pdf
PDF
Model Code of Practice - Construction Work - 21102022 .pdf
PPTX
Construction Project Organization Group 2.pptx
PPTX
Sustainable Sites - Green Building Construction
PDF
Digital Logic Computer Design lecture notes
PDF
Enhancing Cyber Defense Against Zero-Day Attacks using Ensemble Neural Networks
PPTX
MET 305 2019 SCHEME MODULE 2 COMPLETE.pptx
PDF
keyrequirementskkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
FINAL REVIEW FOR COPD DIANOSIS FOR PULMONARY DISEASE.pptx
OOP with Java - Java Introduction (Basics)
BMEC211 - INTRODUCTION TO MECHATRONICS-1.pdf
Lecture Notes Electrical Wiring System Components
UNIT-1 - COAL BASED THERMAL POWER PLANTS
Mohammad Mahdi Farshadian CV - Prospective PhD Student 2026
Mechanical Engineering MATERIALS Selection
UNIT 4 Total Quality Management .pptx
MCN 401 KTU-2019-PPE KITS-MODULE 2.pptx
CARTOGRAPHY AND GEOINFORMATION VISUALIZATION chapter1 NPTE (2).pptx
ASol_English-Language-Literature-Set-1-27-02-2023-converted.docx
Evaluating the Democratization of the Turkish Armed Forces from a Normative P...
Automation-in-Manufacturing-Chapter-Introduction.pdf
Model Code of Practice - Construction Work - 21102022 .pdf
Construction Project Organization Group 2.pptx
Sustainable Sites - Green Building Construction
Digital Logic Computer Design lecture notes
Enhancing Cyber Defense Against Zero-Day Attacks using Ensemble Neural Networks
MET 305 2019 SCHEME MODULE 2 COMPLETE.pptx
keyrequirementskkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
Ad

FlutterNinjas 2024: Exploring Full-Stack Dart for Firebase Server-Side Development

  • 1. FlutterNinjas 2024 Exploring Full-Stack Dart for Firebase Server-Side Development Kosuke (@kosukesaigusa) Hello, Flutter Ninjas! FlutterNinjas 2024 kosukesaigusa 1
  • 2. About me Kosuke Saigusa (@kosukesaigusa) Application Engineer located in Japan Flutter, Dart Lover OSS & Community Contributor pub.dev geoflutterfire_plus flutterfire_gen ... Hold & Speak at Tech Conferences in Japan FlutterNinjas 2024 kosukesaigusa 2
  • 4. Goal Exploring Full-Stack Dart for Firebase Server-Side Development Develop server-side processes for Firebase using Dart Integration of various GCP services Implement solutions with pub.dev packages: functions_framework dart_firebase_admin FlutterNinjas 2024 kosukesaigusa 4
  • 5. First Demo Let's see sample app! FlutterNinjas 2024 kosukesaigusa 5
  • 8. Cloud Run FlutterNinjas 2024 Cloud Run is a managed compute platform that lets you run containers directly on top of Google's scalable infrastructure. You can deploy code written in any programming language on Cloud Run if you can build a container image from it. “ “ kosukesaigusa 8
  • 9. Compile Dart Program to Executable bin/hello.dart void main(List<String> arguments) { print('Hello, Flutter Ninjas!'); } Compile to executable: dart compile exe bin/hello.dart -o bin/hello Run: $ ./bin/hello Hello, Flutter Ninjas! FlutterNinjas 2024 kosukesaigusa 9
  • 11. functions_framework package Developed by GoogleCloudPlatform organization Provides a framework to write Dart functions and deploy it on Cloud Run, GAE, ...etc FlutterNinjas 2024 kosukesaigusa 11
  • 12. Write HTTP Function in Dart Write function with @CloudFunction in bin/functions.dart : import 'package:functions_framework/functions_framework.dart'; import 'package:shelf/shelf.dart'; @CloudFunction() Response hello(Request request) => Response.ok('Hello, Flutter Ninjas!'); Generate code: dart pub run build_runner build -d FlutterNinjas 2024 kosukesaigusa 12
  • 13. Generated code bin/server.dart : import 'package:functions_framework/serve.dart'; import 'package:hello_server/functions.dart' as function_library; Future<void> main(List<String> args) async { await serve(args, _nameToFunctionTarget); } FunctionTarget? _nameToFunctionTarget(String name) => switch (name) { 'hello' => FunctionTarget.http(function_library.hello), _ => null }; FlutterNinjas 2024 kosukesaigusa 13
  • 14. Launch server: $ dart run bin/server.dart Listening on :8080 Request to server: $ curl http://localhost:8080 Hello, Flutter Ninjas! FlutterNinjas 2024 kosukesaigusa 14
  • 15. Run in Container Dockerfile FROM dart:stable AS build WORKDIR /app COPY . . RUN dart pub get RUN dart pub run build_runner build -d RUN dart compile exe bin/server.dart -o bin/server FROM scratch COPY --from=build /runtime/ / COPY --from=build /app/bin/server /app/bin/ EXPOSE 8080 ENTRYPOINT ["/app/bin/server", "--target=hello", "--signature-type=http"] FlutterNinjas 2024 kosukesaigusa 15
  • 16. Build container: docker build -t hello . Run it: $ docker run -it -p 8080:8080 --name app hello Listening on :8080 Request to server: $ curl http://localhost:8080 Hello, Flutter Ninjas! FlutterNinjas 2024 kosukesaigusa 16
  • 17. Demo Try to run hello function on local machine! FlutterNinjas 2024 kosukesaigusa 17
  • 18. Deploy HTTP Function on Cloud Run Deploy on Cloud Run with Dockerfile using gcloud CLI: gcloud run deploy hello # Function (service) name --source=. # Path to Dockerfile --platform=managed # For Cloud Run --allow-unauthenticated # For public access Request to Cloud Run: $ curl https://hello-<generated-url>-an.a.run.app Hello, Flutter Ninjas! Be careful of unauthenticated functions. FlutterNinjas 2024 kosukesaigusa 18
  • 20. Demo Deploy hello function to Cloud Run! FlutterNinjas 2024 kosukesaigusa 20
  • 23. dart_firebase_admin package Developed by invertase organization Remi is the main contributor FlutterNinjas 2024 kosukesaigusa 23
  • 24. dart_firebase_admin package final adminApp = FirebaseAdminApp.initializeApp( 'your-project-id', Credential.fromServiceAccountParams( clientId: 'your-client-id', privateKey: 'your-private-key', email: 'your-email', ), ); final firestore = Firestore(adminApp); final auth = Auth(adminApp); final messaging = Messaging(adminApp); FlutterNinjas 2024 kosukesaigusa 24
  • 25. Example: Send Cloud Messaging Future<void> main async { final messaging = Messaging(adminApp); await messaging.send( TokenMessage( token: 'some-fcm-token', notification: Notification( title: 'FlutterNinjas 2024!', body: 'Welcome to FlutterNinjas!', ), ), ); } FlutterNinjas 2024 kosukesaigusa 25
  • 26. Demo Send FCM to mobile app from local admin SDK! FlutterNinjas 2024 kosukesaigusa 26
  • 28. Transfer Cloud Firestore event to Cloud Run FlutterNinjas 2024 kosukesaigusa 28
  • 29. Eventarc FlutterNinjas 2024 Eventarc lets you build event- driven architectures without having to implement, customize, or maintain the underlying infrastructure. Eventarc offers a standardized solution to manage the flow of state changes, called events, between decoupled microservices. “ “ kosukesaigusa 29
  • 30. CloudEvents FlutterNinjas 2024 CloudEvents is a specification for describing event data in a common way. CloudEvents seeks to dramatically simplify event declaration and delivery across services, platforms, and beyond! “ “ kosukesaigusa 30
  • 31. Write CloudEvents triggered Function in Dart FlutterNinjas 2024 kosukesaigusa 31
  • 32. Write CloudEvents triggered Function in Dart Define function with @CloudFunction() , and give two parameters: CloudEvent event RequestContext context @CloudFunction() void oncreateevent(CloudEvent event, RequestContext context) => Response.ok('Hello, Flutter Ninjas!'); Only lowercase letters, numbers and '-' are allowed for function name. FlutterNinjas 2024 kosukesaigusa 32
  • 33. Deploy CloudEvents triggered Function on Cloud Run Set --signature-type=cloudevent to ENTRYPOINT option: FROM dart:stable AS build WORKDIR /app COPY . . RUN dart pub get RUN dart pub run build_runner build -d RUN dart compile exe bin/server.dart -o bin/server FROM scratch COPY --from=build /runtime/ / COPY --from=build /app/bin/server /app/bin/ EXPOSE 8080 ENTRYPOINT ["/app/bin/server", "--target=oncreateevent", "--signature-type=cloudevent"] FlutterNinjas 2024 kosukesaigusa 33
  • 34. Deploy Eventarc trigger Deploy Eventarc trigger using gcloud CLI Transfer: from Cloud Firestore: type=google.cloud.firestore.document.v1.created to Cloud Run: oncreateevent gcloud eventarc triggers create oncreateevent # Trigger name --destination-run-service=oncreateevent # Destination function name --event-filters="type=google.cloud.firestore.document.v1.created" # Event type --event-filters="database=(default)" --event-filters="namespace=(default)" --event-filters-path-pattern="document=events/{eventId}" # Target path --event-data-content-type="application/protobuf" --service-account="your-service-account-name@project-id.iam.gserviceaccount.com" FlutterNinjas 2024 kosukesaigusa 34
  • 38. How to handle Raw CloudEvents data? Request body is in application/protobuf byte data format: [10, 195, 3, 10, 84, 112, 114, 111, 106, 101, 99, 116, 115, 47, 102, 117 ...] FlutterNinjas 2024 kosukesaigusa 38
  • 39. How to handle Raw CloudEvents data? CloudEvents metadata found in header such as: Triggered document Triggered event type { "ce-dataschema": "https://github.com/googleapis/.../events/cloud/firestore/v1/data.proto", "authorization": "Bearer ...", "ce-subject": "documents/todos/6iGrCr5nJar6NNB8gPog", "ce-source": "//firestore.googleapis.com/.../databases/(default)", "ce-type": "google.cloud.firestore.document.v1.created", // Triggered event type "content-type": "application/protobuf", "ce-document": "todos/6iGrCr5nJar6NNB8gPog", // Triggered document "ce-project": "...", ... } FlutterNinjas 2024 kosukesaigusa 39
  • 40. firebase-functions (Node.js) Node.js SDK provides: Document path parameters from context.params.documentId Triggered DocumentSnapshot snapshot import * as functions from 'firebase-functions' const onCreateTodo = functions .region(`asia-northeast1`) .firestore.document(`todos/{todoId}`) .onCreate(async (snapshot, context) => { const todoId = context.params.todoId const data = snapshot.data() const title = data.title // ... }) FlutterNinjas 2024 kosukesaigusa 40
  • 41. Possible to write in Dart? FlutterNinjas 2024 kosukesaigusa 41
  • 42. dart_firebase_functions package Still in early stages Provides Node.js-like Firebase functions capability in Dart! FlutterNinjas 2024 kosukesaigusa 42
  • 43. onCreate @OnDocumentCreated('todos/{todoId}') Future<void> oncreatetodo( ({String todoId}) params, QueryDocumentSnapshot snapshot, RequestContext context, ) async { final todoId = params.todoId; final data = snapshot.data(); final title = data?['title']; // ... } const onCreateTodo = functions .region(`asia-northeast1`) .firestore.document(`todos/{todoId}`) .onCreate(async (snapshot, context) => { const todoId = context.params.todoId const data = snapshot.data() const title = data.title // ... }) FlutterNinjas 2024 kosukesaigusa 43
  • 44. onUpdate @OnDocumentUpdated('todos/{todoId}') Future<void> onupdatetodo( ({String todoId}) params, ({ QueryDocumentSnapshot before, QueryDocumentSnapshot after, }) snapshot, RequestContext context, ) async { final todoId = params.todoId; final before = snapshot.before.data(); final after = snapshot.after.data(); final newTitle = after.title; // ... } const onUpdateTodo = functions .region(`asia-northeast1`) .firestore.document(`todos/{todoId}`) .onUpdate(async (snapshot, context) => { const todoId = context.params.todoId const before = snapshot.before.data() const after = snapshot.after.data() const newTitle = after.title // ... }) FlutterNinjas 2024 kosukesaigusa 44
  • 45. onDelete @OnDocumentDeleted('todos/{todoId}') Future<void> ondeletetodo( ({String todoId}) params, QueryDocumentSnapshot snapshot, RequestContext context, ) async { final todoId = params.todoId; final data = snapshot.data(); final title = data?.title; // ... } const onDeleteTodo = functions .region(`asia-northeast1`) .firestore.document(`todos/{todoId}`) .onUpdate(async (snapshot, context) => { const todoId = context.params.todoId const data = snapshot.data() const title = data.title // ... }) FlutterNinjas 2024 kosukesaigusa 45
  • 46. onWrite @OnDocumentUpdated('todos/{todoId}') Future<void> onwritetodo( ({String todoId}) params, ({ QueryDocumentSnapshot before, QueryDocumentSnapshot after, }) snapshot, RequestContext context, ) async { final todoId = params.todoId; final before = snapshot.before.data(); final after = snapshot.after.data(); final newTitle = after.title; // ... } const onWriteTodo = functions .region(`asia-northeast1`) .firestore.document(`todos/{todoId}`) .onWrite(async (snapshot, context) => { const todoId = context.params.todoId const before = snapshot.before.data() const after = snapshot.after.data() const newTitle = after?.title // ... }) FlutterNinjas 2024 kosukesaigusa 46
  • 47. Nested Collection @OnDocumentCreated('foos/{fooId}/bars/{barId}') Future<void> oncreatebar( ({String fooId, String barId}) params, QueryDocumentSnapshot snapshot, RequestContext context, ) async { final fooId = params.fooId; final barId = params.barId; final data = snapshot.data(); // ... } FlutterNinjas 2024 kosukesaigusa 47
  • 48. Write Firestore triggered function in Dart: @OnDocumentCreated('todos/{todoId}') Future<void> oncreatetodo( ({String todoId}) params, QueryDocumentSnapshot snapshot, RequestContext context, ) async { // Use Dart Firebase Admin SDK here. } Generate code: dart pub run build_runner build -d FlutterNinjas 2024 kosukesaigusa 48
  • 49. Deploy it on Cloud Run Set --signature-type=cloudevent to ENTRYPOINT option: FROM dart:stable AS build WORKDIR /app COPY . . RUN dart pub get RUN dart pub run build_runner build -d RUN dart compile exe bin/server.dart -o bin/server FROM scratch COPY --from=build /runtime/ / COPY --from=build /app/bin/server /app/bin/ EXPOSE 8080 ENTRYPOINT ["/app/bin/server", "--target=oncreateevent", "--signature-type=cloudevent"] FlutterNinjas 2024 kosukesaigusa 49
  • 50. Final Demo Let's see sample app's server-side code! FlutterNinjas 2024 kosukesaigusa 50
  • 51. Summary In container, Dart executable can be run (Cloud Run) HTTP and CloudEvents triggered functions are available in Dart, thanks to functions_framework package Firebase Admin SDK is available, thanks to dart_firebase_admin package Eventarc transfers CloudEvents from Cloud Firestore to Cloud Run dart_firebase_function package provides Node.js-like Firebase functions capability in Dart FlutterNinjas 2024 kosukesaigusa 51
  • 52. Explore Full-Stack Dart FlutterNinjas 2024 kosukesaigusa 52