Skip to content
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

feat(messaging): add support for exporting delivery metrics to BigQuery #9636

Merged
merged 13 commits into from Oct 6, 2022
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
61 changes: 61 additions & 0 deletions docs/cloud-messaging/receive.md
Expand Up @@ -339,3 +339,64 @@ Here's how to use the second method:
},
}
```


## Enable message delivery data export

You can export your message data into BigQuery for further analysis. BigQuery allows you to analyze the data using BigQuery SQL,
export it to another cloud provider, or use the data for your custom ML models. An export to BigQuery
includes all available data for messages, regardless of message type or whether the message is sent via
the API or the Notifications composer.

To enable the export, first follow the steps [described here](https://firebase.google.com/docs/cloud-messaging/understand-delivery?platform=ios#bigquery-data-export),
then follow these instructions:

### Android

You can use the following code:
```dart
await FirebaseMessaging.instance.setDeliveryMetricsExportToBigQuery(true);
```

### iOS

For iOS, you need to change the `AppDelegate.m` with the following content.

```objective-c
#import "AppDelegate.h"
#import "GeneratedPluginRegistrant.h"
#import <Firebase/Firebase.h>

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[GeneratedPluginRegistrant registerWithRegistry:self];
// Override point for customization after application launch.
return [super application:application didFinishLaunchingWithOptions:launchOptions];
}

- (void)application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
[[FIRMessaging extensionHelper] exportDeliveryMetricsToBigQueryWithMessageInfo:userInfo];
}

@end
```

### Web

For Web, you need to change your service worker in order to use the v9 version of the SDK.
The v9 version needs to be bundled, so you need to use a bundler like `esbuild` for instance
to get the service worker to work.
See [the example app](https://github.com/firebase/flutterfire/blob/master/packages/firebase_messaging/firebase_messaging/example/bundled-service-worker) to see how to achieve this.

Once you've migrated to the v9 SDK, you can use the following code:

``` typescript
const messaging = getMessaging(app);
experimentalSetDeliveryMetricsExportedToBigQueryEnabled(messaging, true);
Lyokone marked this conversation as resolved.
Show resolved Hide resolved
```

Don't forget to run `yarn build` in order to export the new version of your service worker to the `web` folder.
Expand Up @@ -251,6 +251,25 @@ private Task<Map<String, Object>> setAutoInitEnabled(Map<String, Object> argumen
return taskCompletionSource.getTask();
}

private Task<Void> setDeliveryMetricsExportToBigQuery(Map<String, Object> arguments) {
TaskCompletionSource<Void> taskCompletionSource = new TaskCompletionSource<>();

cachedThreadPool.execute(
() -> {
try {
FirebaseMessaging firebaseMessaging =
FlutterFirebaseMessagingUtils.getFirebaseMessagingForArguments(arguments);
Boolean enabled = (Boolean) Objects.requireNonNull(arguments.get("enabled"));
firebaseMessaging.setDeliveryMetricsExportToBigQuery(enabled);
taskCompletionSource.setResult(null);
} catch (Exception e) {
taskCompletionSource.setException(e);
}
});

return taskCompletionSource.getTask();
}

private Task<Map<String, Object>> getInitialMessage() {
TaskCompletionSource<Map<String, Object>> taskCompletionSource = new TaskCompletionSource<>();

Expand Down Expand Up @@ -447,6 +466,9 @@ public void onMethodCall(final MethodCall call, @NonNull final Result result) {
case "Messaging#setAutoInitEnabled":
methodCallTask = setAutoInitEnabled(call.arguments());
break;
case "Messaging#setDeliveryMetricsExportToBigQuery":
methodCallTask = setDeliveryMetricsExportToBigQuery(call.arguments());
break;
case "Messaging#requestPermission":
if (Build.VERSION.SDK_INT >= 33) {
// Android version >= Android 13 requires user input if notification permission not set/granted
Expand Down
Expand Up @@ -32,7 +32,6 @@
/build/

# Web related
lib/generated_plugin_registrant.dart

# Symbolication related
app.*.symbols
Expand Down
@@ -0,0 +1,45 @@
import { initializeApp } from 'firebase/app';
import {
experimentalSetDeliveryMetricsExportedToBigQueryEnabled,
getMessaging,
isSupported,
onBackgroundMessage
} from 'firebase/messaging/sw';

declare var self: ServiceWorkerGlobalScope;

self.addEventListener('install', (event) => {
console.log(self);
console.log(event);
});

const app = initializeApp({
apiKey: 'AIzaSyAgUhHU8wSJgO5MVNy95tMT07NEjzMOfz0',
authDomain: 'react-native-firebase-testing.firebaseapp.com',
databaseURL: 'https://react-native-firebase-testing.firebaseio.com',
projectId: 'react-native-firebase-testing',
storageBucket: 'react-native-firebase-testing.appspot.com',
messagingSenderId: '448618578101',
appId: '1:448618578101:web:ecaffe2bc4511738',
});

isSupported().then((isSupported) => {
if (isSupported) {
const messaging = getMessaging(app);

experimentalSetDeliveryMetricsExportedToBigQueryEnabled(messaging, true);

onBackgroundMessage(messaging, ({ notification: notification }) => {
const { title, body, image } = notification ?? {};

if (!title) {
return;
}

self.registration.showNotification(title, {
body,
icon: image || '/assets/icons/icon-72x72.png',
});
});
}
});
@@ -0,0 +1,11 @@
{
"dependencies": {
"firebase": "9"
},
"devDependencies": {
"esbuild": "^0.15.10"
},
"scripts": {
"build": "esbuild firebase-messaging-sw.ts --outdir=../web --bundle --sourcemap --minify --format=esm"
}
}
@@ -0,0 +1,8 @@
{
"compilerOptions": {
"lib": [
"webworker",
"es6"
]
}
}