Step 1: Create a Flutter project
If you haven't installed Flutter yet, follow the instructions on the official Flutter website to do so. After that, create a new Flutter project using the following command:
flutter create push_notification
cd push_notification
Step 2: Set Up dependencies
Add the plugins to your pubspec.yaml file and run flutter pub get
to install the dependencies as shown below.
dependencies:
firebase_core: ^3.12.0
flutter_local_notifications: ^19.0.0
firebase_messaging: ^15.2.2
googleapis_auth: ^1.6.0
http: ^1.2.1
Step 3: Create your Firebase project
1. Create a Firebase Project
Go to the Firebase Consoleand log in with your Google account.
Click on Create a project, enter the project name, and follow the setup instructions.
2. Add Your Flutter App to Firebase
In the Firebase console, select your project and click Add app.
Choose the platform: Android or iOS.
For Android, provide the package name (found in android/app/build.gradle
).
For iOS, provide the Bundle ID (found in ios/Runner.xcodeproj
).
3. Download the Configuration File
For Android, download the google-services.json file and place it inside android/app/.
For iOS, download the GoogleService-Info.plist file and place it inside ios/Runner/.
4. Configure Firebase in the Flutter Project
Update the Android configuration:
Modify android/build.gradle and android/app/build.gradle to include Firebase dependencies.
5. Initialize Firebase in Flutter
import 'package:firebase_core/firebase_core.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(MyApp());
}
Step 4: Create a file named notification_service.dart
in your project. Then, copy and paste the following content into the file.
import 'dart:convert';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
class AppNotification {
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
AndroidNotificationChannel channel = const AndroidNotificationChannel(
'high_app_notif_channel', // id
'High Importance Notifications', // title
description: 'This channel is used for important notifications', // description
importance: Importance.max,
showBadge: true
);
initializeFcmNotification() async {
await flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()
?.createNotificationChannel(channel);
const AndroidInitializationSettings initializationSettingsAndroid =
AndroidInitializationSettings('@mipmap/ic_launcher');
final DarwinInitializationSettings initializationSettingsIOS =
DarwinInitializationSettings(
requestSoundPermission: true,
requestBadgePermission: true,
requestAlertPermission: true,
defaultPresentAlert: true,
defaultPresentSound: true,
defaultPresentBadge: true,
);
final InitializationSettings initializationSettings =
InitializationSettings(
android: initializationSettingsAndroid,
iOS: initializationSettingsIOS,
);
await flutterLocalNotificationsPlugin.initialize(
initializationSettings,
onDidReceiveNotificationResponse: (payload) async{
},
);
await flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
IOSFlutterLocalNotificationsPlugin>()
?.requestPermissions(
alert: true,
badge: true,
sound: true,
);
await FirebaseMessaging.instance
.setForegroundNotificationPresentationOptions(
alert: true,
badge: true,
sound: true,
);
FirebaseMessaging.onMessage.listen((RemoteMessage message) async {
RemoteNotification? notification = message.notification;
AndroidNotification? android = message.notification?.android;
if (notification != null && android != null) {
flutterLocalNotificationsPlugin.show(
notification.hashCode,
notification.title,
notification.body,
NotificationDetails(
///android platform specific
android: AndroidNotificationDetails(channel.id, channel.name,
channelDescription: channel.description,
importance: Importance.max,
priority: Priority.high,
channelShowBadge: true,
enableVibration: true,
enableLights: true,
icon: android.smallIcon
),
iOS: const DarwinNotificationDetails(
presentSound: true, presentBadge: true, presentAlert: true),
),
payload: jsonEncode(message.data),
);
}
},
);
FirebaseMessaging.onMessageOpenedApp.listen(
(RemoteMessage message) {
//log('Message Opened CallBack $message');
//log('Message Opened CallBack');
},
);
}
}
Step 5: Go to your Firebase project
Select the project, click on the settings icon, and navigate to Project settings.
Step 6: Create a file named constant.dart
in your project. Then, copy and paste the following content into the file.
class AppConstant{
static final fcmUrl = "https://fcm.googleapis.com/v1/projects";
static final googleApi = "https://www.googleapis.com/auth/cloud-platform";
static final api = '${AppConstant.fcmUrl}/students-app-4b35f/messages:send';
}
In the following line:
static final api = '${AppConstant.fcmUrl}/students-app-4b35f/messages:send';
students-app-4b35f is the project ID. Copy it and replace it with the correct value from your Firebase project.
Step 7: Navigate through the menu bar and click on Service accounts
Then, click on Firebase Admin SDK with the key icon. Next, click on the Generate a new private key button. Save the file securely in a safe location.
Open the downloaded file and copy its content. It is in JSON format.
Step 8: Create a file named notification_network.dart
in your project. Then, copy and paste the following content into the file.
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:googleapis_auth/auth_io.dart';
import 'package:http/http.dart' as http;
import 'package:push_notification/constant.dart';
class SendNotificationAccess{
static final List<String> scopes = [
AppConstant.googleApi
];
static Future<String> getAccessToken() async {
final serviceAccountCredentials = ServiceAccountCredentials.fromJson({
"type": "service_account",
"project_id": "students-app-4b35f",
"private_key_id": "2fa48b2f70407670e0c15998be363fb0ed399f82",
"private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDVHiDLCJDkNJhc\naA6v3Be7cu3bnfZc3E8reHl0c+lxZl2ygN1dWOpdM8ErhlF8aOHdsgYrGJ3txLhU\nPwHf3WpEiHsm2+dXBoEUPDm4kQkZRy0+HYr0jD2MuMeCiC9Sua62of/gp9tQp6m2\nwpKTle4ZPRpYv5AdTqTitl8EJKGj1JP0+mw19K3o7gTMyoY65T/Aw0RGkjBUBDVm\nZSz6nZYYW4H8M93KjO8jCeCWxUYfUe1qKlkJGLaKbxEOQJ6PiD+Vp6Jk4TOkmHht\n8IKmrm7PFt5Dul2D8aT/CorpMmWopjLp2ZhQOArhzByPpMpUyPPlAsleoYXdbSkX\nD29dBJabAgMBAAECggEAB6m8KyDFOPdtLRFuycMDtXFF/ToaVC91x03fLCFI2ROB\ntfvtOcCLOMu2G+8J+gu5Z2PR1fXeI+EJcboMQrTu78TqjLSmhloNBSG/P5QzfA2z\nokKkrvNl+SvhvJ9R+EsF7bo4fab7e1R0BUbMx3LCK3Unf95ve6ZKxn4hP4BjsYTP\n7otywZn3g4H2B47EPJfEL0VJK87hM85Z+f4679m0kcVgYqbcrGUCi6iNy0fLZ0Fu\nQtT4DvoSTqbsVD6zhakpFbtgJdMCslZYAjI02/qptTB/6RrbYJmOr3LLfM6kNJiL\n3/V1rLRb9WGrucfGGh2f25huEm1oBFPCoMRulMSUwQKBgQD8At1X8a6ZTrBKS1wH\nNc3sXb5e8y/DSv5xHU3gObgrTsNDlo6mNpsZrbFXkjaKdANZkB1JNgjknhgHVRQ/\njzkenYbDj8qSDYjV90EBJJSXhFv9QSbU0IiUci+N4vaX3hl+fMbCSYJZ5GtlzAPu\nRAZuJa0GCEkxeR6oCyc4y1bfWwKBgQDYfatODjQI0XwwpRYWzJmojZuGh+eA5Tih\nwZmPxeDBJ8mn7v0Dg3dobJcBg0V+HyFwBxweqLvsImpgjy6tgWccT0IuK0YMZT9J\nwhwUzEv0v4uOpyFcHE4ldkLnxmVo85YoxjolzSEPXjZjgA6YLh8HU22y8uQ0Q716\n9b0n08QJwQKBgHScCrmn3keYDqDCEBpR/jASDIW492/hYq0Khz9q1dpMPrQmlWk5\nuTj/kyDXSh90oRwvQC3hL+pBcRLrfkwOxLpy36nb/jrowllnaI/T0mHt3/bmz8YH\nnDs8Pt7jl4EcRyWtLPc3tnZL6JoY9fSpS2RqUI6LBPs8dUACsSpphJAjAoGAY/FI\nFyXJcdS7330nAGl9+mk9RlMRVdj8VviYWt5ADwu+Na/H0Ept4qBW6hTfDQV0G1K8\n8Y52CuIsd91B8EmP/2q7o7LIiMpo+DULX7Kc0iVnWPjhFrPeg77fzj4x7MyfIr24\ndGEJhR26QB8LHcgU/P3P48/r+BDZtZ0isPM7SkECgYEAgyAR1hG0rfrd9ajbGLpx\nXGJ7fo6vQW2OG96jGXpg12N70JwKtoAYw2ZaRn7ajSXXh8JFlyw5334uOO97+65D\n6dVG2T0KNh5FsrVptNZgZuc/PJXf4mEkYWVRHzE3VFfc0y4RBgVsN8cHpH9nIe3K\nhCfESjU6fePEAo1dFIUfTco=\n-----END PRIVATE KEY-----\n",
"client_email": "firebase-adminsdk-fbsvc@students-app-4b35f.iam.gserviceaccount.com",
"client_id": "110426202408684217122",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-fbsvc%40students-app-4b35f.iam.gserviceaccount.com",
"universe_domain": "googleapis.com"
}
);
var client = http.Client();
AuthClient authClient = await clientViaServiceAccount(serviceAccountCredentials, scopes);
final accessTokenData = authClient.credentials.accessToken.data;
client.close();
return accessTokenData;
}
static sendNotificationWithHttp({required String token,required String title,required String body}) async {
String accessToken = await getAccessToken();
Map<String, dynamic> payload = {
"message": {
"token": token,
"notification": {
"body": body,
"title": title
}
}
};
final response = await http.post(Uri.parse(AppConstant.api),
headers: {
'Authorization': 'Bearer $accessToken',
'Content-Type': 'application/json',
},
body: jsonEncode(payload));
if (response.statusCode == 200) {
if (kDebugMode) {
print('Notification send');
}
} else {
if (kDebugMode) {
print('Notification Not send');
}
}
}
}
Replace this part of the code (the JSON) with the content of the JSON file you downloaded.
{
"type": "service_account",
"project_id": "students-app-4b35f",
"private_key_id": "2fa48b2f70407670e0c15998be363fb0ed399f82",
"private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDVHiDLCJDkNJhc\naA6v3Be7cu3bnfZc3E8reHl0c+lxZl2ygN1dWOpdM8ErhlF8aOHdsgYrGJ3txLhU\nPwHf3WpEiHsm2+dXBoEUPDm4kQkZRy0+HYr0jD2MuMeCiC9Sua62of/gp9tQp6m2\nwpKTle4ZPRpYv5AdTqTitl8EJKGj1JP0+mw19K3o7gTMyoY65T/Aw0RGkjBUBDVm\nZSz6nZYYW4H8M93KjO8jCeCWxUYfUe1qKlkJGLaKbxEOQJ6PiD+Vp6Jk4TOkmHht\n8IKmrm7PFt5Dul2D8aT/CorpMmWopjLp2ZhQOArhzByPpMpUyPPlAsleoYXdbSkX\nD29dBJabAgMBAAECggEAB6m8KyDFOPdtLRFuycMDtXFF/ToaVC91x03fLCFI2ROB\ntfvtOcCLOMu2G+8J+gu5Z2PR1fXeI+EJcboMQrTu78TqjLSmhloNBSG/P5QzfA2z\nokKkrvNl+SvhvJ9R+EsF7bo4fab7e1R0BUbMx3LCK3Unf95ve6ZKxn4hP4BjsYTP\n7otywZn3g4H2B47EPJfEL0VJK87hM85Z+f4679m0kcVgYqbcrGUCi6iNy0fLZ0Fu\nQtT4DvoSTqbsVD6zhakpFbtgJdMCslZYAjI02/qptTB/6RrbYJmOr3LLfM6kNJiL\n3/V1rLRb9WGrucfGGh2f25huEm1oBFPCoMRulMSUwQKBgQD8At1X8a6ZTrBKS1wH\nNc3sXb5e8y/DSv5xHU3gObgrTsNDlo6mNpsZrbFXkjaKdANZkB1JNgjknhgHVRQ/\njzkenYbDj8qSDYjV90EBJJSXhFv9QSbU0IiUci+N4vaX3hl+fMbCSYJZ5GtlzAPu\nRAZuJa0GCEkxeR6oCyc4y1bfWwKBgQDYfatODjQI0XwwpRYWzJmojZuGh+eA5Tih\nwZmPxeDBJ8mn7v0Dg3dobJcBg0V+HyFwBxweqLvsImpgjy6tgWccT0IuK0YMZT9J\nwhwUzEv0v4uOpyFcHE4ldkLnxmVo85YoxjolzSEPXjZjgA6YLh8HU22y8uQ0Q716\n9b0n08QJwQKBgHScCrmn3keYDqDCEBpR/jASDIW492/hYq0Khz9q1dpMPrQmlWk5\nuTj/kyDXSh90oRwvQC3hL+pBcRLrfkwOxLpy36nb/jrowllnaI/T0mHt3/bmz8YH\nnDs8Pt7jl4EcRyWtLPc3tnZL6JoY9fSpS2RqUI6LBPs8dUACsSpphJAjAoGAY/FI\nFyXJcdS7330nAGl9+mk9RlMRVdj8VviYWt5ADwu+Na/H0Ept4qBW6hTfDQV0G1K8\n8Y52CuIsd91B8EmP/2q7o7LIiMpo+DULX7Kc0iVnWPjhFrPeg77fzj4x7MyfIr24\ndGEJhR26QB8LHcgU/P3P48/r+BDZtZ0isPM7SkECgYEAgyAR1hG0rfrd9ajbGLpx\nXGJ7fo6vQW2OG96jGXpg12N70JwKtoAYw2ZaRn7ajSXXh8JFlyw5334uOO97+65D\n6dVG2T0KNh5FsrVptNZgZuc/PJXf4mEkYWVRHzE3VFfc0y4RBgVsN8cHpH9nIe3K\nhCfESjU6fePEAo1dFIUfTco=\n-----END PRIVATE KEY-----\n",
"client_email": "firebase-adminsdk-fbsvc@students-app-4b35f.iam.gserviceaccount.com",
"client_id": "110426202408684217122",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-fbsvc%40students-app-4b35f.iam.gserviceaccount.com",
"universe_domain": "googleapis.com"
}
Step 9: Create a file named form_screen.dart
in your project. Then, copy and paste the following content into the file.
import 'dart:developer';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
import 'package:push_notification/notification_network.dart';
class FormScreen extends StatefulWidget {
const FormScreen({super.key, required this.title});
final String title;
@override
State<FormScreen> createState() => _FormScreenState();
}
class _FormScreenState extends State<FormScreen> {
TextEditingController titleCtr = TextEditingController();
TextEditingController descriptionCtr = TextEditingController();
void _incrementCounter() async{
String? fcmToken = await FirebaseMessaging.instance.getToken();
log("fcmToken fcmToken $fcmToken");
SendNotificationAccess.sendNotificationWithHttp(
token: fcmToken!,body: descriptionCtr.text.trim(),title: titleCtr.text.trim());
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: Text(widget.title),
),
body: Center(
child: Padding(
padding: const EdgeInsets.only(left: 15,right: 15),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
TextFormField(
controller: titleCtr,
decoration: InputDecoration(
hintText: "Title"
),
),
SizedBox(height: 50),
TextFormField(
controller: descriptionCtr,
decoration: InputDecoration(
hintText: "Descripton"
),
)
],
),
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: const Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
If everything is set up correctly, call your view in the main.dart
file and run the project.
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:push_notification/form_screen.dart';
import 'package:push_notification/notification_service.dart';
void main() async{
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
final AppNotification appNotification = AppNotification();
appNotification.initializeFcmNotification();
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Push Notifications',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
),
home: const FormScreen(title: 'Push Notifications'),
);
}
}
Top comments (0)