Skip to content

Commit bf9ede5

Browse files
committed
2 parents d7c0d92 + 265ef5e commit bf9ede5

File tree

3 files changed

+222
-8
lines changed

3 files changed

+222
-8
lines changed

README.md

Lines changed: 147 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Firebase Functions for Dart
1+
# Firebase SDK for Dart Functions
22

33
[![Tests](https://github.com/invertase/firebase_functions/actions/workflows/test.yml/badge.svg)](https://github.com/invertase/firebase_functions/actions/workflows/test.yml)
44
[![PR Checks](https://github.com/invertase/firebase_functions/actions/workflows/test.yml/badge.svg)](https://github.com/invertase/firebase_functions/actions/workflows/pr-checks.yml)
@@ -17,8 +17,11 @@ This package provides a complete Dart implementation of Firebase Cloud Functions
1717
| **Realtime Database** | ✅ Complete | `onValueCreated`, `onValueUpdated`, `onValueDeleted`, `onValueWritten` |
1818
| **Storage** | ✅ Complete | `onObjectFinalized`, `onObjectArchived`, `onObjectDeleted`, `onObjectMetadataUpdated` |
1919
| **Scheduler** | ✅ Complete | `onSchedule` |
20-
| **Firebase Alerts** | ✅ Complete | Crashlytics, Billing, Performance alerts |
20+
| **Firebase Alerts** | ✅ Complete | `onInAppFeedbackPublished`, `onNewAnrIssuePublished`, `onNewFatalIssuePublished`, `onNewNonfatalIssuePublished`, `onNewTesterIosDevicePublished`, `onPlanAutomatedUpdatePublished`, `onPlanUpdatePublished`, `onRegressionAlertPublished`, `onStabilityDigestPublished`, `onThresholdAlertPublished`, `onVelocityAlertPublished` |
21+
| **Eventarc** | ✅ Complete | `onCustomEventPublished` |
2122
| **Identity Platform** | ✅ Complete | `beforeUserCreated`, `beforeUserSignedIn` (+ `beforeEmailSent`, `beforeSmsSent`*) |
23+
| **Remote Config** | ✅ Complete | `onConfigUpdated` |
24+
| **Test Lab** | ✅ Complete | `onTestMatrixCompleted` |
2225

2326
## Table of Contents
2427

@@ -34,6 +37,8 @@ This package provides a complete Dart implementation of Firebase Cloud Functions
3437
- [Scheduler Triggers](#scheduler-triggers)
3538
- [Firebase Alerts](#firebase-alerts)
3639
- [Identity Platform (Auth Blocking)](#identity-platform-auth-blocking)
40+
- [Remote Config](#remote-config)
41+
- [Test Lab](#test-lab)
3742
- [Parameters & Configuration](#parameters--configuration)
3843
- [Project Configuration](#project-configuration)
3944
- [Development](#development)
@@ -498,6 +503,17 @@ firebase.scheduler.onSchedule(
498503
## Firebase Alerts
499504

500505
```dart
506+
// App Distribution new tester iOS device
507+
firebase.alerts.appDistribution.onNewTesterIosDevicePublished(
508+
(event) async {
509+
final payload = event.data?.payload;
510+
print('New tester iOS device:');
511+
print(' Tester: ${payload?.testerName} (${payload?.testerEmail})');
512+
print(' Device: ${payload?.testerDeviceModelName}');
513+
print(' Identifier: ${payload?.testerDeviceIdentifier}');
514+
},
515+
);
516+
501517
// Crashlytics fatal issues
502518
firebase.alerts.crashlytics.onNewFatalIssuePublished(
503519
(event) async {
@@ -507,6 +523,54 @@ firebase.alerts.crashlytics.onNewFatalIssuePublished(
507523
},
508524
);
509525
526+
// Crashlytics ANR (Application Not Responding) issues
527+
firebase.alerts.crashlytics.onNewAnrIssuePublished(
528+
(event) async {
529+
final issue = event.data?.payload.issue;
530+
print('ANR issue: ${issue?.title}');
531+
print('App: ${event.appId}');
532+
},
533+
);
534+
535+
// Crashlytics regression alerts
536+
firebase.alerts.crashlytics.onRegressionAlertPublished(
537+
(event) async {
538+
final payload = event.data?.payload;
539+
print('Regression: ${payload?.type}');
540+
print('Issue: ${payload?.issue.title}');
541+
print('Resolved: ${payload?.resolveTime}');
542+
},
543+
);
544+
545+
// Crashlytics non-fatal issues
546+
firebase.alerts.crashlytics.onNewNonfatalIssuePublished(
547+
(event) async {
548+
final issue = event.data?.payload.issue;
549+
print('Non-fatal issue: ${issue?.title}');
550+
print('App: ${event.appId}');
551+
},
552+
);
553+
554+
// Crashlytics stability digest
555+
firebase.alerts.crashlytics.onStabilityDigestPublished(
556+
(event) async {
557+
final payload = event.data?.payload;
558+
print('Stability digest: ${payload?.digestDate}');
559+
print('Trending issues: ${payload?.trendingIssues.length ?? 0}');
560+
},
561+
);
562+
563+
// Crashlytics velocity alerts
564+
firebase.alerts.crashlytics.onVelocityAlertPublished(
565+
(event) async {
566+
final payload = event.data?.payload;
567+
print('Velocity alert: ${payload?.issue.title}');
568+
print('Crash count: ${payload?.crashCount}');
569+
print('Percentage: ${payload?.crashPercentage}%');
570+
print('First version: ${payload?.firstVersion}');
571+
},
572+
);
573+
510574
// Billing plan updates
511575
firebase.alerts.billing.onPlanUpdatePublished(
512576
(event) async {
@@ -516,6 +580,16 @@ firebase.alerts.billing.onPlanUpdatePublished(
516580
},
517581
);
518582
583+
// Billing automated plan updates
584+
firebase.alerts.billing.onPlanAutomatedUpdatePublished(
585+
(event) async {
586+
final payload = event.data?.payload;
587+
print('Automated plan update:');
588+
print(' Plan: ${payload?.billingPlan}');
589+
print(' Type: ${payload?.notificationType}');
590+
},
591+
);
592+
519593
// Performance threshold alerts
520594
firebase.alerts.performance.onThresholdAlertPublished(
521595
options: const AlertOptions(appId: '1:123456789:ios:abcdef'),
@@ -526,6 +600,45 @@ firebase.alerts.performance.onThresholdAlertPublished(
526600
print('Actual: ${payload?.violationValue}');
527601
},
528602
);
603+
604+
// App Distribution in-app feedback
605+
firebase.alerts.appDistribution.onInAppFeedbackPublished(
606+
(event) async {
607+
final payload = event.data?.payload;
608+
print('In-app feedback:');
609+
print(' Tester: ${payload?.testerEmail}');
610+
print(' App version: ${payload?.appVersion}');
611+
print(' Text: ${payload?.text}');
612+
print(' Console: ${payload?.feedbackConsoleUri}');
613+
},
614+
);
615+
```
616+
617+
## Eventarc
618+
619+
```dart
620+
// Custom event (default Firebase channel)
621+
firebase.eventarc.onCustomEventPublished(
622+
eventType: 'com.example.myevent',
623+
(event) async {
624+
print('Event: ${event.type}');
625+
print('Source: ${event.source}');
626+
print('Data: ${event.data}');
627+
},
628+
);
629+
630+
// With channel and filters
631+
firebase.eventarc.onCustomEventPublished(
632+
eventType: 'com.example.filtered',
633+
options: const EventarcTriggerOptions(
634+
channel: 'my-channel',
635+
filters: {'category': 'important'},
636+
),
637+
(event) async {
638+
print('Event: ${event.type}');
639+
print('Data: ${event.data}');
640+
},
641+
);
529642
```
530643

531644
## Identity Platform (Auth Blocking)
@@ -569,6 +682,38 @@ firebase.identity.beforeUserSignedIn(
569682

570683
> **Note**: `beforeEmailSent` and `beforeSmsSent` are also available but cannot be tested with the Firebase Auth emulator (emulator only supports `beforeUserCreated` and `beforeUserSignedIn`). They work in production deployments.
571684
685+
## Remote Config
686+
687+
Trigger a function when Firebase Remote Config is updated.
688+
689+
```dart
690+
firebase.remoteConfig.onConfigUpdated((event) async {
691+
final data = event.data;
692+
print('Remote Config updated:');
693+
print(' Version: ${data?.versionNumber}');
694+
print(' Description: ${data?.description}');
695+
print(' Update Origin: ${data?.updateOrigin.value}');
696+
print(' Update Type: ${data?.updateType.value}');
697+
print(' Updated By: ${data?.updateUser.email}');
698+
});
699+
```
700+
701+
## Test Lab
702+
703+
Trigger a function when a Firebase Test Lab test matrix completes.
704+
705+
```dart
706+
firebase.testLab.onTestMatrixCompleted((event) async {
707+
final data = event.data;
708+
print('Test matrix completed:');
709+
print(' Matrix ID: ${data?.testMatrixId}');
710+
print(' State: ${data?.state.value}');
711+
print(' Outcome: ${data?.outcomeSummary.value}');
712+
print(' Client: ${data?.clientInfo.client}');
713+
print(' Results URI: ${data?.resultStorage.resultsUri}');
714+
});
715+
```
716+
572717
## Parameters & Configuration
573718

574719
### Defining Parameters

example/alerts/bin/server.dart

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,17 @@ import 'package:firebase_functions/firebase_functions.dart';
66

77
void main(List<String> args) async {
88
await fireUp(args, (firebase) {
9+
// App Distribution new tester iOS device alert
10+
firebase.alerts.appDistribution.onNewTesterIosDevicePublished((
11+
event,
12+
) async {
13+
final payload = event.data?.payload;
14+
print('New tester iOS device:');
15+
print(' Tester: ${payload?.testerName} (${payload?.testerEmail})');
16+
print(' Device: ${payload?.testerDeviceModelName}');
17+
print(' Identifier: ${payload?.testerDeviceIdentifier}');
18+
});
19+
920
// Crashlytics new fatal issue alert
1021
firebase.alerts.crashlytics.onNewFatalIssuePublished((event) async {
1122
final issue = event.data?.payload.issue;
@@ -16,6 +27,50 @@ void main(List<String> args) async {
1627
print(' App ID: ${event.appId}');
1728
});
1829

30+
// Crashlytics new ANR issue alert
31+
firebase.alerts.crashlytics.onNewAnrIssuePublished((event) async {
32+
final issue = event.data?.payload.issue;
33+
print('New ANR issue in Crashlytics:');
34+
print(' Issue ID: ${issue?.id}');
35+
print(' Title: ${issue?.title}');
36+
print(' App ID: ${event.appId}');
37+
});
38+
39+
// Crashlytics regression alert
40+
firebase.alerts.crashlytics.onRegressionAlertPublished((event) async {
41+
final payload = event.data?.payload;
42+
print('Crashlytics regression:');
43+
print(' Type: ${payload?.type}');
44+
print(' Issue: ${payload?.issue.title}');
45+
print(' Resolved: ${payload?.resolveTime}');
46+
});
47+
48+
// Crashlytics new non-fatal issue alert
49+
firebase.alerts.crashlytics.onNewNonfatalIssuePublished((event) async {
50+
final issue = event.data?.payload.issue;
51+
print('New non-fatal issue in Crashlytics:');
52+
print(' Issue ID: ${issue?.id}');
53+
print(' Title: ${issue?.title}');
54+
print(' App ID: ${event.appId}');
55+
});
56+
57+
// Crashlytics stability digest alert
58+
firebase.alerts.crashlytics.onStabilityDigestPublished((event) async {
59+
final payload = event.data?.payload;
60+
print('Stability digest: ${payload?.digestDate}');
61+
print('Trending issues: ${payload?.trendingIssues.length ?? 0}');
62+
});
63+
64+
// Crashlytics velocity alert
65+
firebase.alerts.crashlytics.onVelocityAlertPublished((event) async {
66+
final payload = event.data?.payload;
67+
print('Crashlytics velocity alert:');
68+
print(' Issue: ${payload?.issue.title}');
69+
print(' Crash count: ${payload?.crashCount}');
70+
print(' Percentage: ${payload?.crashPercentage}%');
71+
print(' First version: ${payload?.firstVersion}');
72+
});
73+
1974
// Billing plan update alert
2075
firebase.alerts.billing.onPlanUpdatePublished((event) async {
2176
final payload = event.data?.payload;
@@ -25,6 +80,14 @@ void main(List<String> args) async {
2580
print(' Type: ${payload?.notificationType}');
2681
});
2782

83+
// Billing automated plan update alert
84+
firebase.alerts.billing.onPlanAutomatedUpdatePublished((event) async {
85+
final payload = event.data?.payload;
86+
print('Billing automated plan update:');
87+
print(' Plan: ${payload?.billingPlan}');
88+
print(' Type: ${payload?.notificationType}');
89+
});
90+
2891
// Performance threshold alert with app ID filter
2992
firebase.alerts.performance.onThresholdAlertPublished(
3093
options: const AlertOptions(appId: '1:123456789:ios:abcdef'),
@@ -39,5 +102,15 @@ void main(List<String> args) async {
39102
print(' Actual: ${payload?.violationValue} ${payload?.violationUnit}');
40103
},
41104
);
105+
106+
// App Distribution in-app feedback alert
107+
firebase.alerts.appDistribution.onInAppFeedbackPublished((event) async {
108+
final payload = event.data?.payload;
109+
print('In-app feedback:');
110+
print(' Tester: ${payload?.testerEmail}');
111+
print(' App version: ${payload?.appVersion}');
112+
print(' Text: ${payload?.text}');
113+
print(' Console: ${payload?.feedbackConsoleUri}');
114+
});
42115
});
43116
}

pubspec.yaml

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: firebase_functions
2-
description: Firebase Functions runtime for Dart - Write serverless functions in Dart with type safety and performance
2+
description: Firebase SDK for Cloud Functions (Dart)
33
version: 0.1.0
44
repository: https://github.com/invertase/firebase-functions-dart
55
publish_to: none
@@ -48,6 +48,7 @@ dependencies:
4848
analyzer: ^10.0.1
4949
glob: ^2.1.3
5050
yaml_edit: ^2.2.3
51+
google_cloud_storage: ^0.5.1
5152

5253
dev_dependencies:
5354
build_runner: ^2.10.5
@@ -62,8 +63,3 @@ dependency_overrides:
6263
url: https://github.com/invertase/dart_firebase_admin.git
6364
ref: next
6465
path: packages/google_cloud_firestore
65-
googleapis_storage:
66-
git:
67-
url: https://github.com/invertase/dart_firebase_admin.git
68-
ref: next
69-
path: packages/googleapis_storage

0 commit comments

Comments
 (0)