Skip to content

Firebase Remote Config Integration #2837

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 36 commits into from
Apr 14, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
9d77e52
add feature flag models
denrase Mar 31, 2025
16ee1e6
add FeatureFlagsIntegration
denrase Mar 31, 2025
956e388
remove comments, add test
denrase Mar 31, 2025
1559285
use bool type for value
denrase Mar 31, 2025
3944ea1
add sentry_firebase package
denrase Apr 1, 2025
e9ce800
add feature flag if provided key is updated from remote config
denrase Apr 1, 2025
e5fdace
format
denrase Apr 1, 2025
4e6bd4c
test wether subscription is canceld on close
denrase Apr 1, 2025
5bfac70
add option to activate remote config
denrase Apr 1, 2025
db48687
Merge branch 'main' into feat/feature-flags-integration
denrase Apr 2, 2025
6dc16c8
review feedback
denrase Apr 2, 2025
42eea2e
Merge branch 'feat/feature-flags-integration' into fear/firebase-feat…
denrase Apr 2, 2025
c8b754d
Merge branch 'main' into feat/feature-flags-integration
denrase Apr 7, 2025
bdfaf44
format cl
denrase Apr 7, 2025
4f247a5
updates
denrase Apr 7, 2025
aa8bcc6
Merge branch 'feat/feature-flags-integration' into fear/firebase-feat…
denrase Apr 7, 2025
1f041dd
Merge branch 'main' into fear/firebase-feature-flags
denrase Apr 7, 2025
112f211
add cl entry
denrase Apr 7, 2025
969e12d
log message
denrase Apr 7, 2025
17fd9c1
update readme
denrase Apr 7, 2025
63c08b0
run flutter test
denrase Apr 7, 2025
0b2b321
use flutter sdk
denrase Apr 7, 2025
2a415c2
fix & format
denrase Apr 7, 2025
52a5a16
fix test expectations
denrase Apr 7, 2025
b64acc2
update example values
denrase Apr 7, 2025
213c627
fix example
denrase Apr 8, 2025
28fd231
add firebase to version bump
denrase Apr 8, 2025
012fd33
update yaml files
denrase Apr 8, 2025
03016ba
make params named
denrase Apr 8, 2025
8c85832
change name to firebase_remote_config
denrase Apr 8, 2025
40a5b23
fix test and added integration
denrase Apr 8, 2025
eac7227
rename package folder, observe all boolean keys
denrase Apr 9, 2025
e147a00
fix analyze warning
denrase Apr 9, 2025
214bd71
Merge branch 'main' into fear/firebase-feature-flags
buenaflor Apr 10, 2025
0f6361e
Merge branch 'main' into fear/firebase-feature-flags
buenaflor Apr 14, 2025
e980c8d
add sample in readme
denrase Apr 14, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .craft.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ targets:
drift:
isar:
link:
firebase_remote_config:
- name: github
- name: registry
sdks:
Expand All @@ -31,4 +32,6 @@ targets:
pub:sentry_hive:
pub:sentry_isar:
# TODO: after we published link we need to add it to the registry repo and then uncomment here
# pub:sentry_link:
# pub:sentry_link:
# TODO: after we published firebase we need to add it to the registry repo and then uncomment here
# pub:sentry_firebase_remote_config:
8 changes: 8 additions & 0 deletions .github/workflows/diagrams.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,14 @@ jobs:
working-directory: ./isar
run: lakos . -i "{test/**,example/**}" | dot -Tsvg -o class-diagram.svg

- name: link
working-directory: ./link
run: lakos . -i "{test/**,example/**}" | dot -Tsvg -o class-diagram.svg

- name: firebase_remote_config
working-directory: ./firebase_remote_config
run: lakos . -i "{test/**,example/**}" | dot -Tsvg -o class-diagram.svg

# Source: https://stackoverflow.com/a/58035262
- name: Extract branch name
shell: bash
Expand Down
56 changes: 56 additions & 0 deletions .github/workflows/firebase_remote_config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
name: sentry-firebase-remote-config
on:
push:
branches:
- main
- release/**
pull_request:
paths:
- '!**/*.md'
- '!**/class-diagram.svg'
- '.github/workflows/firebase_remote_config.yml'
- '.github/workflows/analyze.yml'
- '.github/actions/dart-test/**'
- '.github/actions/coverage/**'
- 'dart/**'
- 'flutter/**'
- 'firebase_remote_config/**'

# https://docs.github.com/en/actions/using-jobs/using-concurrency#example-using-a-fallback-value
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true

jobs:
build:
name: '${{ matrix.os }} | ${{ matrix.sdk }}'
runs-on: ${{ matrix.os }}-latest
timeout-minutes: 30
strategy:
fail-fast: false
matrix:
os: [macos, ubuntu, windows]
sdk: [stable, beta]

steps:
- uses: actions/checkout@v4

- uses: ./.github/actions/flutter-test
with:
directory: firebase_remote_config
web: false

# TODO: don't set coverage for now to finish publishing it
# - uses: ./.github/actions/coverage
# if: runner.os == 'Linux' && matrix.sdk == 'stable'
# with:
# token: ${{ secrets.CODECOV_TOKEN }}
# directory: firebase_remote_config
# coverage: sentry_firebase_remote_config
# min-coverage: 55

analyze:
uses: ./.github/workflows/analyze.yml
with:
package: firebase_remote_config
sdk: flutter
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,20 @@
// Manually track a feature flag
Sentry.addFeatureFlag('my-feature', true);
```
- Firebase Remote Config Integration ([#2837](https://github.com/getsentry/sentry-dart/pull/2837))
```dart
// Add the integration to automatically track feature flags from firebase remote config.
await SentryFlutter.init(
(options) {
options.dsn = 'https://[email protected]/add-your-dsn-here';
options.addIntegration(
SentryFirebaseRemoteConfigIntegration(
firebaseRemoteConfig: yourRirebaseRemoteConfig,
),
);
},
);
```

### Behavioral changes

Expand Down
14 changes: 14 additions & 0 deletions firebase_remote_config/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Omit committing pubspec.lock for library packages; see
# https://dart.dev/guides/libraries/private-files#pubspeclock.
pubspec.lock

# Flutter/Dart/Pub related
**/doc/api/
**/ios/Flutter/.last_build_id
.dart_tool/
.flutter-plugins
.flutter-plugins-dependencies
.packages
.pub-cache/
.pub/
/build/
10 changes: 10 additions & 0 deletions firebase_remote_config/.metadata
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.

version:
revision: "09de023485e95e6d1225c2baa44b8feb85e0d45f"
channel: "stable"

project_type: package
1 change: 1 addition & 0 deletions firebase_remote_config/CHANGELOG.md
21 changes: 21 additions & 0 deletions firebase_remote_config/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2019 Sentry

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
98 changes: 98 additions & 0 deletions firebase_remote_config/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
<p align="center">
<a href="https://sentry.io" target="_blank" align="center">
<img src="https://sentry-brand.storage.googleapis.com/sentry-logo-black.png" width="280">
</a>
<br />
</p>


===========

<p align="center">
<a href="https://sentry.io" target="_blank" align="center">
<img src="https://sentry-brand.storage.googleapis.com/sentry-logo-black.png" width="280">
</a>
<br />
</p>

Sentry integration for `firebase_remote_config` package
===========

| package | build | pub | likes | popularity | pub points |
|-------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------| ------- |
| 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)

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

#### Usage

- Sign up for a Sentry.io account and get a DSN at https://sentry.io.

- Follow the installing instructions on [pub.dev](https://pub.dev/packages/sentry/install).

- Initialize the Sentry SDK using the DSN issued by Sentry.io.

- Call...

```dart
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_remote_config_example/home_page.dart';
import 'package:flutter/material.dart';
import 'package:sentry_flutter/sentry_flutter.dart';
import 'package:sentry_firebase_remote_config/sentry_firebase_remote_config.dart';

import 'firebase_options.dart';

Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);

final remoteConfig = FirebaseRemoteConfig.instance;
await remoteConfig.setConfigSettings(RemoteConfigSettings(
fetchTimeout: const Duration(minutes: 1),
minimumFetchInterval: const Duration(hours: 1),
));

await SentryFlutter.init(
(options) {
options.dsn = 'https://[email protected]/add-your-dsn-here';

final sentryFirebaseRemoteConfigIntegration = SentryFirebaseRemoteConfigIntegration(
firebaseRemoteConfig: remoteConfig,
// Don't call `await remoteConfig.activate();` when firebase config is updated. Per default this is true.
activateOnConfigUpdated: false,
);
options.addIntegration(sentryFirebaseRemoteConfigIntegration);
},
);

runApp(const RemoteConfigApp());
}

class RemoteConfigApp extends StatelessWidget {
const RemoteConfigApp({Key? key}) : super(key: key);

@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Remote Config Example',
home: const HomePage(),
theme: ThemeData(
useMaterial3: true,
primarySwatch: Colors.blue,
),
);
}
}
```

#### Resources

* [![Flutter docs](https://img.shields.io/badge/documentation-sentry.io-green.svg?label=flutter%20docs)](https://docs.sentry.io/platforms/flutter/)
* [![Dart docs](https://img.shields.io/badge/documentation-sentry.io-green.svg?label=dart%20docs)](https://docs.sentry.io/platforms/dart/)
* [![Discussions](https://img.shields.io/github/discussions/getsentry/sentry-dart.svg)](https://github.com/getsentry/sentry-dart/discussions)
* [![Discord Chat](https://img.shields.io/discord/621778831602221064?logo=discord&logoColor=ffffff&color=7389D8)](https://discord.gg/PXa5Apfe7K)
* [![Stack Overflow](https://img.shields.io/badge/stack%20overflow-sentry-green.svg)](https://stackoverflow.com/questions/tagged/sentry)
* [![Twitter Follow](https://img.shields.io/twitter/follow/getsentry?label=getsentry&style=social)](https://twitter.com/intent/follow?screen_name=getsentry)
32 changes: 32 additions & 0 deletions firebase_remote_config/analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
include: package:lints/recommended.yaml

analyzer:
language:
strict-casts: true
strict-inference: true
strict-raw-types: true
errors:
# treat missing required parameters as a warning (not a hint)
missing_required_param: error
# treat missing returns as a warning (not a hint)
missing_return: error
# allow having TODOs in the code
todo: ignore
# allow self-reference to deprecated members (we do this because otherwise we have
# to annotate every member in every test, assert, etc, when we deprecate something)
deprecated_member_use_from_same_package: warning
# ignore sentry/path on pubspec as we change it on deployment
invalid_dependency: ignore
exclude:
- example/**
- test/mocks/mocks.mocks.dart

linter:
rules:
- prefer_final_locals
- prefer_single_quotes
- prefer_relative_imports
- unnecessary_brace_in_string_interps
- implementation_imports
- require_trailing_commas
- unawaited_futures
1 change: 1 addition & 0 deletions firebase_remote_config/dartdoc_options.yaml
52 changes: 52 additions & 0 deletions firebase_remote_config/example/example.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_remote_config_example/home_page.dart';
import 'package:flutter/material.dart';
import 'package:sentry_flutter/sentry_flutter.dart';
import 'package:sentry_firebase_remote_config/sentry_firebase_remote_config.dart';

import 'firebase_options.dart';

Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);

final remoteConfig = FirebaseRemoteConfig.instance;
await remoteConfig.setConfigSettings(RemoteConfigSettings(
fetchTimeout: const Duration(minutes: 1),
minimumFetchInterval: const Duration(hours: 1),
));

await SentryFlutter.init(
(options) {
options.dsn = 'https://[email protected]/add-your-dsn-here';

final sentryFirebaseRemoteConfigIntegration =
SentryFirebaseRemoteConfigIntegration(
firebaseRemoteConfig: remoteConfig,
// Don't call `await remoteConfig.activate();` when firebase config is updated. Per default this is true.
activateOnConfigUpdated: false,
);
options.addIntegration(sentryFirebaseRemoteConfigIntegration);
},
);

runApp(const RemoteConfigApp());
}

class RemoteConfigApp extends StatelessWidget {
const RemoteConfigApp({Key? key}) : super(key: key);

@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Remote Config Example',
home: const HomePage(),
theme: ThemeData(
useMaterial3: true,
primarySwatch: Colors.blue,
),
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
library;

export 'src/sentry_firebase_remote_config_integration.dart';
Loading
Loading