Flutter and Automated Firebase push Notification Complete Integration.
Hello Everyone, today we’ll be covering flutter and firebase push notification.
As I have been working on an App like uber so I faced issues regarding push notifications to send a notification to available drivers about location etc.
What you need to do is to first set up the flutter project with a firebase with cloud messaging and cloud firestore.
Step 1: First we will install to firebase functions in our PC:
- Go to Command prompt and write: ‘npm install -g firebase-tools’ and wait until it completes.
- then write ‘firebase login’ and you’ll be prompt to google chrome for login and then log in from the account you’re associated with firebase. if you want to login from different id then use: ‘firebase login — reauth ’ where ‘ — ‘ is a double dash.
- Now create a directory with the command: mkdir firebasefunctions
- now then go to that directory: ‘cd firebasefunctions’
- now write ‘firebase init functions’ and press y.
- now select the default project either create new or choose an existing project in which you want to integrate firebase functions
- After selecting the project you’ll get two options javascript or typescript, select javascript.
- then it’ll ask to install dependencies through npm, press y. it’ll take a couple of minutes
- now enter ‘code .’ to open the project in visual studio code or any other ide you have.
you’ve successfully installed firebase functions on your PC for a specific project.
Step 2: Now enable cloud firestore from firebase database options and create a collection, as we are doing it with dummy data you can also integrate it according to your need, let's do it with me with dummy data:
Go to firebase console and go to the database and create firestore DB in a test mode then do this what I am doing:
- tap on start collection and name collections with offers as below:
2) In document id field press auto-id and then give field names as below, all should be the same to work correctly and save it, always remember field name should be the same.
3)Now tap on add document and again do the same for document id press auto-id and the same name with different data, always remember field name should be the same.
Step 2: Now go visual studio code where you have your firebase setup, inside firebase folder goto index.js and remove all the code and copy-paste the following code:
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
var msgData;
exports.offerTrigger = functions.firestore.document(
'offers/{offerId}'
).onCreate((snapshot,context)=>{
msgData = snapshot.data();
admin.firestore().collection('tokens').get().then((snapshots)=>{
var tokens = [];
if(snapshots.empty)
{
console.log('No Devices Found');
}
else{
for(var pushTokens of snapshots.docs){
tokens.push(pushTokens.data().token);
}
var payload ={
'notification':{
'title': 'From ' + msgData.businessType,
'body': 'Offer is : ' + msgData.offer,
'sound': 'default',
},
'data':{
'sendername': msgData.businessType,
'message': msgData.offer,
}
};
return admin.messaging().sendToDevice(tokens, payload).then((response) => {
console.log('pushed them all')
}).catch((err) => {
console.log(err);
});
}
});
});
Now let's understand this what happening here because this is the main part to set up your notification system:
- First, we have initialized the firebase app.
exports.offerTrigger = functions.firestore.document(
'offers/{offerId}'
)
This method will always call whenever we add a new document or data into our offers collection that we have already created above as dummy while integrating into your project always remember that you’ve to put here the collection name where little change in a collection will push a notification to the user.
admin.firestore().collection('tokens').get().then((snapshots)=>{
var tokens = [];
if(snapshots.empty)
{
console.log('No Devices Found');
}
else{
for(var pushTokens of snapshots.docs){
tokens.push(pushTokens.data().token);
}
var payload ={
'notification':{
'title': 'From ' + msgData.businessType,
'body': 'Offer is : ' + msgData.offer,
'sound': 'default',
},
'data':{
'sendername': msgData.businessType,
'message': msgData.offer,
}
};
return admin.messaging().sendToDevice(tokens, payload).then((response) => {
console.log('pushed them all')
}).catch((err) => {
console.log(err);
});
}
});
});
Now this collection will work on tokens node, don't worry we will generate token dynamically but first, we may understand this code, This Code will go inside the tokens collection and get all the tokens, if there is no token so no devices found else if it finds one token then it’ll loop through the documents and take out a token from it, now understand this:
The Business type and offer will get from the offer collection we created like below:
as you can see business-type and offer is the same as written in our index.js file.
for(var pushTokens of snapshots.docs){
tokens.push(pushTokens.data().token);
}
Tokens.push is adding data into tokens array.
pushTokens.data().token
now the ‘token’ written here is the field name of the document i.e if you save your token key as MyToken then ‘token’ will be replace to ‘MyToken’.
var payload ={
'notification':{
'title': 'From ' + msgData.businessType,
'body': 'Offer is : ' + msgData.offer,
'sound': 'default',
},
'data':{
'sendername': msgData.businessType,
'message': msgData.offer,
}
};
return admin.messaging().sendToDevice(tokens, payload).then((response) => {
console.log('pushed them all')
}).catch((err) => {
console.log(err);
});
}
});
});
Now payload is the notification setup data that we want to send to the user.
notification: it should be the same as well, a notification will take the title and body which will be shown on the notification to the user.
data: this takes who sends the data and what’s the message.
return admin.messaging().sendToDevice(tokens, payload).then((response) => {
console.log('pushed them all')
}).catch((err) => {
console.log(err);
});
}
});
});
This part tell us that push this notification to all the tokens available in our collections.
Now open the cmd where you’ have your firebase functions, for eg you have saved your firebase functions inside D drive then go to D drive and inside address bar remove all and write cmd and press enter, and then cd firebasefunctions after you’re at the address where you deploy your firebase functions run this command:
‘firebase deploy — only functions’ where — means two dashes, if you get an auth error then write this command ‘firebase login — reauth’ where — means two dashes.
Then goto firebase and check out the functions under develop hierarchy you’ll see a trigger appears there. if you don't see then you probably have forgotten step above.
Now let's go towards our app, go to main.dart, remove all the code, and copy-paste the following code:
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final FirebaseMessaging firebaseMessaging = FirebaseMessaging();
final _firestore = Firestore.instance;
final key = GlobalKey<ScaffoldState>();
@override
void initState() {
super.initState();
firebaseMessaging.getToken().then((token) {
saveTokens(token);
});
}
Future<void> saveTokens(var token) async {
try {
await _firestore.collection('tokens').add({
'token': token,
});
} catch (e) {
print(e);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
key: key,
appBar: AppBar(
title: Text('Push Notification'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[],
),
),
);
}
}
Now here in init state we get token and save it to the firestore with a new collection, you need to do it once so that your device id is saved into the firestore.
Let’s run the app, you’ll see the firestore as below:
A tokens collection is generated with a token field which is the same as in our index.js field.
Now copy-paste the code in init state:
@override
void initState() {
super.initState();
// firebaseMessaging.getToken().then((token) {
// saveTokens(token);
// });
firebaseMessaging.configure(
//called when app is in foreground
onMessage: (Map<String, dynamic> message) async {
print('init called onMessage');
final snackBar = SnackBar(
content: Text(message['notification']['body']),
action: SnackBarAction(label: 'GO', onPressed: () {}),
);
key.currentState.showSnackBar(snackBar);
},
//called when app is completely closed and open from push notification
onLaunch: (Map<String, dynamic> message) async {
print('init called onLaunch');
},
//called when app is in background and open from push notification
onResume: (Map<String, dynamic> message) async {
print('init called onResume');
},
);
}
we have commented out the token code because we don’t want it anymore as we saved a token already.
Let's understand the config part:
- OnMessage: This method is called when the app is in the foreground, i.e the user is using the app, so we show some type of pop up to the user about notification for e.g a snack bar or a dialog or a toast, etc.
- onLaunch: This method is called when the app is completely destroyed i.e It’s not in background or completely closed and whenever a notification occurs the app will open with it.
- onResume: This method is called when the app is not completely destroyed i.e It’s in the background and the user is not using the application and whenever a notification occurs the app will open with it.
The Map<String,dynamic> message is the JSON we return on index.js file i.e:
var payload ={
'notification':{
'title': 'From ' + msgData.businessType,
'body': 'Offer is : ' + msgData.offer,
'sound': 'default',
},
'data':{
'sendername': msgData.businessType,
'message': msgData.offer,
}
};
This is the JSON we get in our ‘Map<String, dynamic> message’ parameter.
Now go to the android folder, then the app , then src then main and then manifest file and copy-paste this intent-filter inside activity tag:
<intent-filter>
<action android:name="FLUTTER_NOTIFICATION_CLICK" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
Now, let’s run the app and check out the notification magic:
- Let’s first check the onMessage state of our application i.e don’t exit the Application and wait to get a notification now go to Firestore and add a new document inside offers node. you may see after you save the document inside a couple of mins you’ll receive a notification as a snack bar in your app.
- Now Let’s make our app in a background state to test our onResume method working or not, so press the home button on your mobile and create a document again inside offers collection. you may see after you save the document inside offers node, a notification will appear on notification bar of your phone when you press the notification it’ll go to the app.
- Now Let’s make our app in a completely destroyed or closed state to test our on launch method working or not, create a document again inside offers collection. you may see after you save the document inside offers node, a notification will appear on the notification bar of your phone. when you press the notification it’ll go to the app.
Keep in mind in the token process, you save the token of each user when you're registering the user in your app.
That’s all for today, we have learned today how to send automated notifications on flutter using firebase push notifications. You can customize it with your needs, it’ll be useful in uber type app or e-commerce or chat app user to user.
This is the basic setup on how to use such notifications. I haven’t added the index.js in GitHub so copy-paste from the above where I explained index.js code.
Leave a clap and also follow me on medium if it is helpful for you.
Thank you.
Github Repo link:
Leave a star and also follow me on GitHub ❤
Thank you again ❤