Flutter Fcm Notification One to One
Key Steps:
Your code is a comprehensive setup for handling Firebase push notifications in a Flutter app. It initializes Firebase Messaging, handles token retrieval and refresh, configures local notifications, and handles incoming messages both when the app is in the foreground and background. Here are a few improvements and considerations for robustness and clarity:
- Token Management: Ensure to handle null values properly when retrieving the token.
- Notification Click Handling: Confirm payload structure to ensure proper handling.
- Error Handling: Add error handling for network requests and potential null values.
- Code Organization: Consider separating platform-specific configurations for better readability.
- Logging: Use a logging library instead of
print
for better log management.
Here's the updated version of your code with some enhancements:
class NotificationService {
String token = "";
FirebaseMessaging messaging = FirebaseMessaging.instance;
late FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
Future<String> getDeviceToken() async {
// String? token = await messaging.getToken();
String? token =
"eUPMI5O5RSmFVTMKpKEIG5:APA91bE8Hm9-ZalZzx4rFr7dZIoauLP7sgYZnPOA3Prl1mPPBYDUI2Y70tXchb4Qdsd01yEOpRhkVindp5QjqMU_50XF-BcjxxF0xnEKLcL9LvTqjkP2V0eUfWxfskHn0obmKUEkVUHX";
return token!;
}
void getToken() async {
await messaging.getToken().then((tokendata) {
token = tokendata!;
print("My Token $token");
});
// saveToken(token);
}
void isTokenrefresh() async {
messaging.onTokenRefresh.listen((event) {
event.toString();
});
}
initLocalNotification(BuildContext context, RemoteMessage message) async {
var androidInitialize =
AndroidInitializationSettings('@mipmap/ic_launcher');
var initializationSettings =
InitializationSettings(android: androidInitialize);
await flutterLocalNotificationsPlugin.initialize(initializationSettings,
onDidReceiveNotificationResponse: (payload) async {
print("payloadaaaaaaaaaaaaaaaaaaa$payload");
handleMessage(context, message);
});
}
firbaseInit(BuildContext context) {
FirebaseMessaging.onMessage.listen((message) async {
print("...................onMessage.......................");
print(
"onMessage: ${message.notification!.title} / ${message.notification!.body} / ${message.notification}");
// print(message.data["id"]);
if (Platform.isIOS) {
forgroundMessage();
}
if (Platform.isAndroid) {
initLocalNotification(context, message);
showNotification(context, message);
} else {
showNotification(context, message);
}
});
}
Future<void> showNotification(
BuildContext context, RemoteMessage message) async {
AndroidNotificationChannel channel = AndroidNotificationChannel(
Random.secure().nextInt(1000).toString(),
"name",
importance: Importance.max,
showBadge: true,
);
// BigTextStyleInformation bigTextStyleInformation = BigTextStyleInformation(
//
// message.notification!.body.toString(),
// htmlFormatBigText: true,
// contentTitle: message.notification!.title.toString(),
// htmlFormatContentTitle: true);
final notificationData = message.data;
final title = notificationData['title'] ?? 'Default Title';
final body = notificationData['body'] ?? 'Default Body';
final imageUrl = notificationData['image'] ??
"https://proshort.ai/static/img/ps_logo.png";
BigPictureStyleInformation bigPictureStyle = BigPictureStyleInformation(
FilePathAndroidBitmap(imageUrl.toString()),
contentTitle: title,
summaryText: body,
);
AndroidNotificationDetails androidNotificationDetails =
AndroidNotificationDetails(
channel.id.toString(), channel.name.toString(),
channelDescription: "Hiiii",
importance: Importance.max,
priority: Priority.high,
ticker: "ticker",
styleInformation: bigPictureStyle,
playSound: true);
const DarwinNotificationDetails darwinNotificationDetails =
DarwinNotificationDetails(
presentAlert: true, presentBadge: true, presentSound: true);
NotificationDetails platformChannelSpecifiics = NotificationDetails(
android: androidNotificationDetails, iOS: darwinNotificationDetails);
Future.delayed(Duration.zero, () async {
await flutterLocalNotificationsPlugin.show(
0,
message.notification!.title.toString(),
message.notification!.body,
platformChannelSpecifiics,
payload: message.data['data'],
);
});
}
void handleMessage(BuildContext context, RemoteMessage message) {
if (message.data['type'] == 'chat') {
// Navigator.push(
// context,
// MaterialPageRoute(
// builder: (context) => MessageScreen(
// id: message.data['id'],
// )));
}
}
Future<void> setupInteractMessage(BuildContext context) async {
// when app is terminated
RemoteMessage? initialMessage =
await FirebaseMessaging.instance.getInitialMessage();
if (initialMessage != null) {
handleMessage(context, initialMessage);
}
//when app ins background
FirebaseMessaging.onMessageOpenedApp.listen((event) {
// handleMessage(context, event);
});
}
Future forgroundMessage() async {
await FirebaseMessaging.instance
.setForegroundNotificationPresentationOptions(
alert: true,
badge: true,
sound: true,
);
}
}
Generate FCM Access Token:
- Use the service account credentials to generate an access token.
import 'package:http/http.dart' as http;
import 'package:googleapis_auth/auth_io.dart' as auth;
import 'dart:convert';
class PushNotificationService {
static Future<String> generateFCMAccessToken() async {
final serviceAccountJson = {
"type": "service_account",
"project_id": "m360ict-335f7",
"private_key_id": "374270491a3bbd9bfd55d720aaa81dcb15ab51e8",
"private_key":
"-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCi1vii0Tb81AJE\nTAH/nosoenxg9EtAMX5JcMZyaG4i78awztyo/u2Kj90kh4taGzXH6/jkTwndTYFl\nJ1wu69Z36d1HJuZ0W4N3NHJJ1REKstWpnGFEGbpEZmwz82B22ig1HlP2JWDtj9AI\nwUm/H8SuIxj+PlTB1lIugjzzMrC8yvhboWeYkR7MPXAnaTmb1u7KCEYK5th1qTXY\n0dWw6N4h92B/HUTb4r6qJjjN5RryF+doandoppzDIghDBdpHZCMLUxgaZ5Deeo/v\nE8N86senGgEMY48Lq/Z4Bj23ntytDtzgUVAS/ylxKSqgirPOE+u52EUcxrLfuXgB\nE0sZdAVtAgMBAAECggEAKWev4PaBnNfrm6IX//84Mxqx9ZUobTIoglQCoaScHJYL\nV3nB8dagX9Mkz90HOeohSqxdpO/T+kly1V2kuumMpwD4GtdxUbTTQMQ9KzjaFHZU\njcQNl1tTWYERkkQYCyB9iMQlZTkr5DvlEdTUA5z4Ta7u8/a1ZnQwgVLsXIpPFjG9\njjx7Wesfkrz/4iirzs1XFsz0aONeiW/ft6hTcsBiFttmKTLMYDtPLdASIKB+E2JH\ngTDZwqEeze6zvsFlGhFvPOhg1+4EstkhNjiS/+st2tHylnl5yo+vGRIEJzXnISKb\niaM+1ybzpy16CKOtbVRGm6E/MVFvUIgo84LmK9KBoQKBgQDhXP8+C8KRMsdTDfS6\nxs6znlUd6asiG2/ADe4TAiUwfI+e5Q6dL6PIDBxgS11COgZl1q3DzVxPiwqd4GaA\nFp5iS+nyxBgA0CGf70svmzHnt+8naZhs7WHM9vpNkubjncWKXnrwPEQ0oK8A7azl\ny32igLM+2vptO/uLqhHdHeL+FwKBgQC4+g4LN+gX5Pl0AJ7tU7lcqKBtO4mEQikY\nw8LGkXSUVygj2dPSw5oKgoU86H9DdZL/fPYsXQ8KvrR0n/5LY6zoOVVFSU0Im3g2\n7BeVWVTeXgaico3s1zskk5ZdoNDS+cCWCWoXqOwyK4dLZvMYmECv+AKRtW/XfcYi\ne3KYKCsvGwKBgEopr3l8pz/fJQco/ZOFnzou7bXVUtL7km/yZZltyE1HgH/6wy9p\nIQ3RJnlt87e6nqZe2nooF6u5hvnjgfe++cpBTzDr5TZHR/l45xY4jVjDB/nBXz7h\nc6De2gozQLZBEmPxqaVrP8rN4il9Dbvllmem0NXrfCP8bFBO3GgW0L9rAoGBAJ21\ndKvT6qoUqypgLSAjNfLuQnlfPYvp7KgUn8g007R16t9GJPeZlYhIZ9jaUUbuw3nY\nzPpeDSkYFzsn/ePBA/aqiy0bpfYkt4X8HM9U7qr4d6ehC6hWiTJSMu144xI9phlF\nxZKOj3Lm8d8z0yexB9YAGhCpJMYRkhBsN/PKq6bpAoGBAN7Ep99yV0ZX3UxcG2Ez\nv/FwNNWIMkTBfQjGbDcM2Xurd5ygj4k5o5GHhVEY6cpXtGFHXGmHJE/L2C6lTl7G\nZ+TA4tyyHucyMmVMWp4dtYcot8AlJulVNqnTjlinGiOFYSU3C47xSR5jFjPVMFZo\nOlfZTDDBAAYKvnzBFDUFHwoY\n-----END PRIVATE KEY-----\n",
"client_email":
"crm-employee-robi@m360ict-335f7.iam.gserviceaccount.com",
"client_id": "108520097675909255711",
"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/crm-employee-robi%40m360ict-335f7.iam.gserviceaccount.com",
"universe_domain": "googleapis.com"
};
List<String> scopes = [
// "https://www.googleapis.com/auth/userinfo.email",
// "https://www.googleapis.com/auth/firebase.database",
"https://www.googleapis.com/auth/firebase.messaging"
];
final auth.ServiceAccountCredentials credentials =
auth.ServiceAccountCredentials.fromJson(serviceAccountJson);
final auth.AutoRefreshingAuthClient client = await auth.clientViaServiceAccount(
credentials, scopes);
final accessToken = client.credentials.accessToken;
client.close();
return accessToken.data;
}
Send Notification:static Future<void> sendNotificationToSelectedDriver(
- Send a push notification using the generated access token and FCM HTTP v1 API.
String token, String title, String body, String fcmToken) async {
final url = Uri.parse('https://fcm.googleapis.com/v1/projects/m360ict-335f7/messages:send');
final headers = {
'Content-Type': 'application/json',
'Authorization': 'Bearer $token',
};
final bodyData = jsonEncode({
'message': {
'token': fcmToken,
'notification': {
'title': title,
'body': body,
},
},
});
print(headers);
print(bodyData);
final response = await http.post(url, headers: headers, body: bodyData);
if (response.statusCode == 200) {
print('Notification sent successfully!');
} else {
print('Failed to send notification. Status code: ${response.statusCode}');
print('Response body: ${response.body}');
}
}
}Test Your AppsElevatedButton(onPressed: ()async{
final accessToken = await PushNotificationService.generateFCMAccessToken();
await PushNotificationService.sendNotificationToSelectedDriver(
accessToken,
'Test Title',
'Test Body',
'$token',
);
}, child: Text("Notification")),
Comments
Post a Comment