Skip to content

Commit b356fb0

Browse files
authored
Firebase Remote Config Integration (#2837)
1 parent 2ed9d5f commit b356fb0

20 files changed

+1542
-2
lines changed

.craft.yml

+4-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ targets:
1818
drift:
1919
isar:
2020
link:
21+
firebase_remote_config:
2122
- name: github
2223
- name: registry
2324
sdks:
@@ -31,4 +32,6 @@ targets:
3132
pub:sentry_hive:
3233
pub:sentry_isar:
3334
# TODO: after we published link we need to add it to the registry repo and then uncomment here
34-
# pub:sentry_link:
35+
# pub:sentry_link:
36+
# TODO: after we published firebase we need to add it to the registry repo and then uncomment here
37+
# pub:sentry_firebase_remote_config:

.github/workflows/diagrams.yml

+8
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,14 @@ jobs:
5151
working-directory: ./isar
5252
run: lakos . -i "{test/**,example/**}" | dot -Tsvg -o class-diagram.svg
5353

54+
- name: link
55+
working-directory: ./link
56+
run: lakos . -i "{test/**,example/**}" | dot -Tsvg -o class-diagram.svg
57+
58+
- name: firebase_remote_config
59+
working-directory: ./firebase_remote_config
60+
run: lakos . -i "{test/**,example/**}" | dot -Tsvg -o class-diagram.svg
61+
5462
# Source: https://stackoverflow.com/a/58035262
5563
- name: Extract branch name
5664
shell: bash
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
name: sentry-firebase-remote-config
2+
on:
3+
push:
4+
branches:
5+
- main
6+
- release/**
7+
pull_request:
8+
paths:
9+
- '!**/*.md'
10+
- '!**/class-diagram.svg'
11+
- '.github/workflows/firebase_remote_config.yml'
12+
- '.github/workflows/analyze.yml'
13+
- '.github/actions/dart-test/**'
14+
- '.github/actions/coverage/**'
15+
- 'dart/**'
16+
- 'flutter/**'
17+
- 'firebase_remote_config/**'
18+
19+
# https://docs.github.com/en/actions/using-jobs/using-concurrency#example-using-a-fallback-value
20+
concurrency:
21+
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
22+
cancel-in-progress: true
23+
24+
jobs:
25+
build:
26+
name: '${{ matrix.os }} | ${{ matrix.sdk }}'
27+
runs-on: ${{ matrix.os }}-latest
28+
timeout-minutes: 30
29+
strategy:
30+
fail-fast: false
31+
matrix:
32+
os: [macos, ubuntu, windows]
33+
sdk: [stable, beta]
34+
35+
steps:
36+
- uses: actions/checkout@v4
37+
38+
- uses: ./.github/actions/flutter-test
39+
with:
40+
directory: firebase_remote_config
41+
web: false
42+
43+
# TODO: don't set coverage for now to finish publishing it
44+
# - uses: ./.github/actions/coverage
45+
# if: runner.os == 'Linux' && matrix.sdk == 'stable'
46+
# with:
47+
# token: ${{ secrets.CODECOV_TOKEN }}
48+
# directory: firebase_remote_config
49+
# coverage: sentry_firebase_remote_config
50+
# min-coverage: 55
51+
52+
analyze:
53+
uses: ./.github/workflows/analyze.yml
54+
with:
55+
package: firebase_remote_config
56+
sdk: flutter

CHANGELOG.md

+14
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,20 @@
99
// Manually track a feature flag
1010
Sentry.addFeatureFlag('my-feature', true);
1111
```
12+
- Firebase Remote Config Integration ([#2837](https://github.com/getsentry/sentry-dart/pull/2837))
13+
```dart
14+
// Add the integration to automatically track feature flags from firebase remote config.
15+
await SentryFlutter.init(
16+
(options) {
17+
options.dsn = 'https://[email protected]/add-your-dsn-here';
18+
options.addIntegration(
19+
SentryFirebaseRemoteConfigIntegration(
20+
firebaseRemoteConfig: yourRirebaseRemoteConfig,
21+
),
22+
);
23+
},
24+
);
25+
```
1226

1327
### Behavioral changes
1428

firebase_remote_config/.gitignore

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Omit committing pubspec.lock for library packages; see
2+
# https://dart.dev/guides/libraries/private-files#pubspeclock.
3+
pubspec.lock
4+
5+
# Flutter/Dart/Pub related
6+
**/doc/api/
7+
**/ios/Flutter/.last_build_id
8+
.dart_tool/
9+
.flutter-plugins
10+
.flutter-plugins-dependencies
11+
.packages
12+
.pub-cache/
13+
.pub/
14+
/build/

firebase_remote_config/.metadata

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# This file tracks properties of this Flutter project.
2+
# Used by Flutter tool to assess capabilities and perform upgrades etc.
3+
#
4+
# This file should be version controlled and should not be manually edited.
5+
6+
version:
7+
revision: "09de023485e95e6d1225c2baa44b8feb85e0d45f"
8+
channel: "stable"
9+
10+
project_type: package

firebase_remote_config/CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../CHANGELOG.md

firebase_remote_config/LICENSE

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2019 Sentry
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

firebase_remote_config/README.md

+98
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
<p align="center">
2+
<a href="https://sentry.io" target="_blank" align="center">
3+
<img src="https://sentry-brand.storage.googleapis.com/sentry-logo-black.png" width="280">
4+
</a>
5+
<br />
6+
</p>
7+
8+
9+
===========
10+
11+
<p align="center">
12+
<a href="https://sentry.io" target="_blank" align="center">
13+
<img src="https://sentry-brand.storage.googleapis.com/sentry-logo-black.png" width="280">
14+
</a>
15+
<br />
16+
</p>
17+
18+
Sentry integration for `firebase_remote_config` package
19+
===========
20+
21+
| package | build | pub | likes | popularity | pub points |
22+
|-------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------| ------- |
23+
| sentry_firebase_remote_config | [![build](https://github.com/getsentry/sentry-dart/actions/workflows/firebase.yml/badge.svg?branch=main)](https://github.com/getsentry/sentry-dart/actions?query=workflow%3Asentry-firebase) | [![pub package](https://img.shields.io/pub/v/sentry_firebase_remote_config.svg)](https://pub.dev/packages/sentry_firebase_remote_config) | [![likes](https://img.shields.io/pub/likes/sentry_firebase_remote_config)](https://pub.dev/packages/sentry_firebase_remote_config/score) | [![popularity](https://img.shields.io/pub/popularity/sentry_firebase_remote_config)](https://pub.dev/packages/sentry_firebase_remote_config/score) | [![pub points](https://img.shields.io/pub/points/sentry_firebase_remote_config)](https://pub.dev/packages/sentry_firebase_remote_config/score)
24+
25+
Integration for [`firebase_remote_config`](https://pub.dev/packages/firebase_remote_config) package. Track changes to firebase boolean values as feature flags in Sentry.io
26+
27+
#### Usage
28+
29+
- Sign up for a Sentry.io account and get a DSN at https://sentry.io.
30+
31+
- Follow the installing instructions on [pub.dev](https://pub.dev/packages/sentry/install).
32+
33+
- Initialize the Sentry SDK using the DSN issued by Sentry.io.
34+
35+
- Call...
36+
37+
```dart
38+
import 'package:firebase_core/firebase_core.dart';
39+
import 'package:firebase_remote_config_example/home_page.dart';
40+
import 'package:flutter/material.dart';
41+
import 'package:sentry_flutter/sentry_flutter.dart';
42+
import 'package:sentry_firebase_remote_config/sentry_firebase_remote_config.dart';
43+
44+
import 'firebase_options.dart';
45+
46+
Future<void> main() async {
47+
WidgetsFlutterBinding.ensureInitialized();
48+
await Firebase.initializeApp(
49+
options: DefaultFirebaseOptions.currentPlatform,
50+
);
51+
52+
final remoteConfig = FirebaseRemoteConfig.instance;
53+
await remoteConfig.setConfigSettings(RemoteConfigSettings(
54+
fetchTimeout: const Duration(minutes: 1),
55+
minimumFetchInterval: const Duration(hours: 1),
56+
));
57+
58+
await SentryFlutter.init(
59+
(options) {
60+
options.dsn = 'https://[email protected]/add-your-dsn-here';
61+
62+
final sentryFirebaseRemoteConfigIntegration = SentryFirebaseRemoteConfigIntegration(
63+
firebaseRemoteConfig: remoteConfig,
64+
// Don't call `await remoteConfig.activate();` when firebase config is updated. Per default this is true.
65+
activateOnConfigUpdated: false,
66+
);
67+
options.addIntegration(sentryFirebaseRemoteConfigIntegration);
68+
},
69+
);
70+
71+
runApp(const RemoteConfigApp());
72+
}
73+
74+
class RemoteConfigApp extends StatelessWidget {
75+
const RemoteConfigApp({Key? key}) : super(key: key);
76+
77+
@override
78+
Widget build(BuildContext context) {
79+
return MaterialApp(
80+
title: 'Remote Config Example',
81+
home: const HomePage(),
82+
theme: ThemeData(
83+
useMaterial3: true,
84+
primarySwatch: Colors.blue,
85+
),
86+
);
87+
}
88+
}
89+
```
90+
91+
#### Resources
92+
93+
* [![Flutter docs](https://img.shields.io/badge/documentation-sentry.io-green.svg?label=flutter%20docs)](https://docs.sentry.io/platforms/flutter/)
94+
* [![Dart docs](https://img.shields.io/badge/documentation-sentry.io-green.svg?label=dart%20docs)](https://docs.sentry.io/platforms/dart/)
95+
* [![Discussions](https://img.shields.io/github/discussions/getsentry/sentry-dart.svg)](https://github.com/getsentry/sentry-dart/discussions)
96+
* [![Discord Chat](https://img.shields.io/discord/621778831602221064?logo=discord&logoColor=ffffff&color=7389D8)](https://discord.gg/PXa5Apfe7K)
97+
* [![Stack Overflow](https://img.shields.io/badge/stack%20overflow-sentry-green.svg)](https://stackoverflow.com/questions/tagged/sentry)
98+
* [![Twitter Follow](https://img.shields.io/twitter/follow/getsentry?label=getsentry&style=social)](https://twitter.com/intent/follow?screen_name=getsentry)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
include: package:lints/recommended.yaml
2+
3+
analyzer:
4+
language:
5+
strict-casts: true
6+
strict-inference: true
7+
strict-raw-types: true
8+
errors:
9+
# treat missing required parameters as a warning (not a hint)
10+
missing_required_param: error
11+
# treat missing returns as a warning (not a hint)
12+
missing_return: error
13+
# allow having TODOs in the code
14+
todo: ignore
15+
# allow self-reference to deprecated members (we do this because otherwise we have
16+
# to annotate every member in every test, assert, etc, when we deprecate something)
17+
deprecated_member_use_from_same_package: warning
18+
# ignore sentry/path on pubspec as we change it on deployment
19+
invalid_dependency: ignore
20+
exclude:
21+
- example/**
22+
- test/mocks/mocks.mocks.dart
23+
24+
linter:
25+
rules:
26+
- prefer_final_locals
27+
- prefer_single_quotes
28+
- prefer_relative_imports
29+
- unnecessary_brace_in_string_interps
30+
- implementation_imports
31+
- require_trailing_commas
32+
- unawaited_futures
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../dart/dartdoc_options.yaml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import 'package:firebase_core/firebase_core.dart';
2+
import 'package:firebase_remote_config_example/home_page.dart';
3+
import 'package:flutter/material.dart';
4+
import 'package:sentry_flutter/sentry_flutter.dart';
5+
import 'package:sentry_firebase_remote_config/sentry_firebase_remote_config.dart';
6+
7+
import 'firebase_options.dart';
8+
9+
Future<void> main() async {
10+
WidgetsFlutterBinding.ensureInitialized();
11+
await Firebase.initializeApp(
12+
options: DefaultFirebaseOptions.currentPlatform,
13+
);
14+
15+
final remoteConfig = FirebaseRemoteConfig.instance;
16+
await remoteConfig.setConfigSettings(RemoteConfigSettings(
17+
fetchTimeout: const Duration(minutes: 1),
18+
minimumFetchInterval: const Duration(hours: 1),
19+
));
20+
21+
await SentryFlutter.init(
22+
(options) {
23+
options.dsn = 'https://[email protected]/add-your-dsn-here';
24+
25+
final sentryFirebaseRemoteConfigIntegration =
26+
SentryFirebaseRemoteConfigIntegration(
27+
firebaseRemoteConfig: remoteConfig,
28+
// Don't call `await remoteConfig.activate();` when firebase config is updated. Per default this is true.
29+
activateOnConfigUpdated: false,
30+
);
31+
options.addIntegration(sentryFirebaseRemoteConfigIntegration);
32+
},
33+
);
34+
35+
runApp(const RemoteConfigApp());
36+
}
37+
38+
class RemoteConfigApp extends StatelessWidget {
39+
const RemoteConfigApp({Key? key}) : super(key: key);
40+
41+
@override
42+
Widget build(BuildContext context) {
43+
return MaterialApp(
44+
title: 'Remote Config Example',
45+
home: const HomePage(),
46+
theme: ThemeData(
47+
useMaterial3: true,
48+
primarySwatch: Colors.blue,
49+
),
50+
);
51+
}
52+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
library;
2+
3+
export 'src/sentry_firebase_remote_config_integration.dart';

0 commit comments

Comments
 (0)