I'm wondering if I can implement push notification in flutter web?
I saw that I can create push notification for mobile app with firbase_messaging
but is it possible to use it for web app? or any other alternative to accomplish it?
In the main app target, select Signing & Capabilities > All > + Capability and then search "push." Double-click on Push Notifications to enable it. Next, enable Background Modes and check Remote Notifications. Now you are ready to send notifications from the OneSignal dashboard!
Push is a flutter package designed to handle push notifications - including background notification, alert notifications and notification taps. Users can avoid using Firebase on all platforms except Android - for example, on iOS, they can use APNs directly.
You will find the firebaseConfig details in the web app you'd have added. For the key, you'll have to generate a new pair. Go to the Cloud Messaging in the project settings, and there you can generate a new pair. When you'll run your app (flutter run -d chrome), you can find your token in the console log.
I'm considering that you've already set up a flutter-web project and have a firebase project.
In the flutter project folder, open index.html and place these scripts in the head section.
<script src="https://www.gstatic.com/firebasejs/7.14.4/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/7.14.4/firebase-analytics.js"></script>
<script src="https://www.gstatic.com/firebasejs/7.14.4/firebase-messaging.js"></script>
Then, in the body, append the code before main.dart.js script is loaded.
<script src="./firebase-messaging-sw.js"></script>
<script src="myjs.js"></script>
<script src="main.dart.js" type="application/javascript"></script>
(where myjs.js is any file where you want to write code, but firebase-messaging-sw.js must be there.)
Now, create two files in the index.html directory:
In firebase-messaging-sw.js, just write
console.log("")
In myjs.js (again, whatever file name you chose), write following code:
var firebaseConfig = {
apiKey: "YOUR_API_KEY",
authDomain: "~~~~~~",
databaseURL: "~~~~~",
projectId: "~~~~~~",
storageBucket: "~~~~~~",
messagingSenderId: "~~~~~~",
appId: "~~~~~~~~~~~~~",
measurementId: "~~~~~~~~~~~"
};
firebase.initializeApp(firebaseConfig);
firebase.analytics();
var messaging = firebase.messaging()
messaging.usePublicVapidKey('Your Key');
messaging.getToken().then((currentToken) => {
console.log(currentToken)
})
You can find these credentials from the firebase console's project settings. You will find the firebaseConfig details in the web app you'd have added. For the key, you'll have to generate a new pair. Go to the Cloud Messaging in the project settings, and there you can generate a new pair.
When you'll run your app (flutter run -d chrome), you can find your token in the console log. Copy that token.
From the Cloud Messaging Section from the side drawer, we can compose a new notification. Enter whatever you like in title and text. Click on send test message. Paste the token you copied from console and click on Test.
You can see the notification popped up.
You can refer this article and firebase documentation for more info.
To implement push notifications and open the app on notification click you need to Change in three files.
1) Firebase-Messaging-sw.js
importScripts("https://www.gstatic.com/firebasejs/7.23.0/firebase-app.js");
importScripts("https://www.gstatic.com/firebasejs/7.23.0/firebase-messaging.js");
firebase.initializeApp({
apiKey: "",
authDomain: "",
projectId: "",
storageBucket: "",
messagingSenderId: "",
appId: "",
measurementId: ""
});
const messaging = firebase.messaging();
messaging.setBackgroundMessageHandler(function (payload) {
const promiseChain = clients
.matchAll({
type: "window",
includeUncontrolled: true
})
.then(windowClients => {
for (let i = 0; i < windowClients.length; i++) {
const windowClient = windowClients[i];
windowClient.postMessage(payload);
}
})
.then(() => {
const title = payload.notification.title;
const options = {
body: payload.notification.score
};
return registration.showNotification(title, options);
});
return promiseChain;
});
self.addEventListener('notificationclick', function (event) {
console.log('notification received: ', event)
});
index.html
<!DOCTYPE html>
<html>
<head>
<!--
If you are serving your web app in a path other than the root, change the
href value below to reflect the base path you are serving from.
The path provided below has to start and end with a slash "/" in order for
it to work correctly.
Fore more details:
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base
-->
<base href="/">
<meta charset="UTF-8">
<meta content="IE=Edge" http-equiv="X-UA-Compatible">
<meta name="description" content="Share pictures and information with other collectors of historical artifacts">
<!-- iOS meta tags & icons -->
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="apple-mobile-web-app-title" content="Militrade">
<link rel="apple-touch-icon" href="icons/Icon-192.png">
<!-- Favicon -->
<link rel="shortcut icon" type="image/x-icon" href="favicon.ico"/>
<link rel="icon" type="image/x-icon" href="favicon.ico"/>
<title>Militrade</title>
<link rel="manifest" href="manifest.json">
</head>
<body>
<script>
if ('serviceWorker' in navigator) {
window.addEventListener('load', function () {
navigator.serviceWorker.register("/firebase-messaging-sw.js");
});
}
</script>
<!-- This script installs service_worker.js to provide PWA functionality to
application. For more information, see:
https://developers.google.com/web/fundamentals/primers/service-workers -->
<!-- The core Firebase JS SDK is always required and must be listed first -->
<script src="https://www.gstatic.com/firebasejs/8.6.1/firebase-app.js"></script>
<!-- TODO: Add SDKs for Firebase products that you want to use
https://firebase.google.com/docs/web/setup#available-libraries -->
<script src="https://www.gstatic.com/firebasejs/8.6.1/firebase-analytics.js"></script>
<script src="https://www.gstatic.com/firebasejs/8.6.1/firebase-firestore.js"></script>
<script src="https://www.gstatic.com/firebasejs/8.6.1/firebase-auth.js"></script>
<script src="https://www.gstatic.com/firebasejs/8.6.1/firebase-messaging.js"></script>
<script src="https://www.gstatic.com/firebasejs/7.20.0/firebase-storage.js"></script>
<script>
// Your web app's Firebase configuration
// For Firebase JS SDK v7.20.0 and later, measurementId is optional
var firebaseConfig = {
apiKey: "",
authDomain: "",
projectId: "",
storageBucket: "",
messagingSenderId: "",
appId: "",
measurementId: ""
};
// Initialize Firebase
firebase.initializeApp(firebaseConfig);
firebase.analytics();
</script>
<script src="main.dart.js" type="application/javascript"></script>
<script type="text/javascript">
let useHtml = true;
if(useHtml) {
window.flutterWebRenderer = "html";
} else {
window.flutterWebRenderer = "canvaskit";
}
</script>
<script>
if ("serviceWorker" in navigator) {
window.addEventListener("load", function () {
navigator.serviceWorker.register("/flutter_service_worker.js");
navigator.serviceWorker.register("/firebase-messaging-sw.js");
});
}
</script>
</body>
</html>
then create push_notification_services.dart file for send push notification
import 'dart:async';
import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:http/http.dart' as http;
final String serverToken =
'';
Future<Map<String, dynamic>> sendPushNotification(
{@required String message,
@required String fcmToken,
@required String title}) async {
print(fcmToken);
await http.post(
Uri.parse('https://fcm.googleapis.com/fcm/send'),
headers: <String, String>{
'Content-Type': 'application/json',
'Authorization': 'key=$serverToken',
},
body: jsonEncode(
<String, dynamic>{
'notification': <String, dynamic>{
"click_action" : ".EditPostPage",
'body': message,
'title': '$title',
'sound': 'default'
},
'priority': 'high',
'data': <String, dynamic>{
'click_action': 'FLUTTER_NOTIFICATION_CLICK',
'id': '1',
'status': 'done'
},
'to': fcmToken.toString().trim(),
},
),
);
final Completer<Map<String, dynamic>> completer =
Completer<Map<String, dynamic>>();
return completer.future;
}
After 3 days I can do it and it's properly working well for me. hope it's helpful for you.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With