Unable to process data from push notification in IOS - flutter

I have set up everything and i do receive a push notification but I am unable to process it. i.e I want a pop up window to show together when i receive the message. The pop
As the notification is received i want to use this function retrieveRideRequestInfo(getRideRequestId(message.data)!, context); to get the data in the notification and build a pop up window. On IOS i get Null check operator used on a null value at (message.data)!
This is the getRideRequestId function
String? getRideRequestId(Map<String, dynamic> message) {
String? rideRequestId = "";
if (Platform.isAndroid) {
// print();
rideRequestId = message['ride_request_id'];
print("This is ride request ID :$rideRequestId");
} else {
//for ios
rideRequestId = message['data'];
}
//doublenotification++;
return rideRequestId;
}
In android it works fine but in Ios I get an error Null check operator used on a null value This is at retrieveRideRequestInfo(getRideRequestId(message.data)!, context);
This is How i send the notification from another device, Is it correct ror ios ?
static sendNotificationToDriver(
String token, context, String rideRequestId) async {
try {
await http.post(
Uri.parse('https://fcm.googleapis.com/fcm/send'),
headers: <String, String>{
'Authorization': serverToken,
'Content-Type': 'application/json',
},
body: jsonEncode({
"to": token,
"collapse_key": "type_a",
"notification": {
"body": "Nepali Rider",
"title": "You have a new Ride"
},
"data": {"ride_request_id": rideRequestId}
}),
);
print('FCM request for device sent!');
} catch (e) {
print(e);
}
print("ride request id :$rideRequestId");
print("ride request id :$token");
print(jsonEncode);
}

Related

i could not accept the payment using flutter 'checkout.com'

I'm trying to enable payment in my app so i choose 'checkout.com' as a payment gateway
there are couples of methods there to accept the payment and i choose the one with token.
i managed to get the token successfully, but accepting the payment does not work. i am not sure if my code is wrong, or their API is broken for some reason. because it does not response me any data or anything the error code is 401
here is my code
Future<bool> makePayment(PaymentCard card, int amount) async {
String? token = await _getPaymentToken(card);
Map<String, dynamic> body = {
"source": {"type": "token", "token": token},
"amount": amount,
"currency": "USD",
};
http.Response respone = await http.post(Uri.parse(_paymentURL),
headers: _Payment_Header, body: jsonEncode(body));
print(respone.body);
if (respone.statusCode == 200) {
var data = await jsonDecode(respone.body);
print(data['response_summary']);
return true;
} else {
print("invalid - payment");
return false;
}
}
static const Map<String, String> _Payment_Header = {
'Content-Type': 'Application/json',
'Authorization': _secret_key,
};
the response body is empty.
this is the url
static const String _paymentURL = 'https://api.sandbox.checkout.com/payments';
also the secret key is correct.
any idea why ? thank you
Could be a couple of issues. You are most likely on the new platform which requires the word Bearer in front of the secret key. Your authorization header value would look similar to 'Bearer sk_xxxx'

http put did not send any response in flutter

Hey I have this app where I can update status, and I use http.put method, but it takes forever to response. I got this error
error
And here is the code for http.put
Future<void> mapEventToState(
Emitter<ReportStatusState> emit, ReportStatusEvent event) async {
emit(ReportStatusLoading());
ReportStatusPut statusPut = event.statusPutBody;
// ReportStatusModel model =
// await apiAuthRepository.updateReportStatus(statusPut, event.id);
ReportStatusModel model = await updateReportStatus({'biaya': '0', 'status': 'SELESAI'}, event.id);
print(model);
if (!model.success) {
emit(ReportStatusFailure(model.message));
}
print(model.code);
emit(ReportStatusSuccess());
}}
Future<ReportStatusModel> updateReportStatus(
Map data, String id) async {
final SharedPreferencesManager sharedPreferencesManager =
locator<SharedPreferencesManager>();
String? token =
sharedPreferencesManager.getString(SharedPreferencesManager.keyAccessToken);
try {
final response = await http.put(
Uri.parse('https://api.komplekku.com/officer/api/report/v1/$id'),
body: json.encode(data),
headers: {'Authorization': 'Bearer $token'});
return ReportStatusModel.fromJson(json.decode(response.body));
} catch (e) {
throw Exception(e);
}
}
There is nothing wrong with the API, I already check using Postman and it worked perfectly fine, Anyone know what went wrong?

Notification being sent to every user instead of a specific user on flutter

I am trying to send notifications to a specific user by using tokens. However, the notification is broadcasted to every user.
This is my code.
For initialization (main.dart):
MessagingService.initialize();
I have 2 types of users and the type of user who is receiving the notification, has the code block below.
To display the notification(homescreen.dart of user receiving the notification):
FirebaseMessaging.instance.getInitialMessage();
FirebaseMessaging.onMessage.listen((event) {
MessagingService.display(event);
});
MessagingService.storeNotificationToken();
Process of sending notification to user:
final userFireStore = await FirebaseFirestore.instance.collection('users').doc(docID).get(); // sends notification
print('receiver ID');
print(userFireStore.data()!['token']);
await sendNotification('Booking Request', 'New booking request received.', userFireStore.data()!['token']);
This class has some of the logic to send notifications.I have the logic on how to display notifications and how users can set the token to receive the notification.
More methods to send notification:
class MessagingService {
static final FlutterLocalNotificationsPlugin
_flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
static void initialize() {
final InitializationSettings initializationSettings =
InitializationSettings(
android: AndroidInitializationSettings("#mipmap/ic_launcher"));
_flutterLocalNotificationsPlugin.initialize(initializationSettings);
}
static void display(RemoteMessage message) async{
try {
print("In Notification method");
// int id = DateTime.now().microsecondsSinceEpoch ~/1000000;
Random random = new Random();
int id = random.nextInt(1000);
final NotificationDetails notificationDetails = NotificationDetails(
android: AndroidNotificationDetails(
"mychanel",
"my chanel",
importance: Importance.max,
priority: Priority.high,
)
);
print("my id is ${id.toString()}");
await _flutterLocalNotificationsPlugin.show(
id,
message.notification!.title,
message.notification!.body,
notificationDetails,);
} on Exception catch (e) {
print('Error>>>$e');
}
}
static storeNotificationToken() async {
try {
final user = await FirebaseAuth.instance.currentUser;
String? token = await FirebaseMessaging.instance.getToken();
await FirebaseFirestore.instance.collection('users').doc(user!.uid).set({
'token': token
}, SetOptions(merge: true));
} on FirebaseAuthException catch (e) {
print(e);
throw CustomException(e.message);
}
}
}
The code block below sends notification based on the token of the receiver:
Future sendNotification(String title, String body, String token) async {
final data = {
'click_action': 'FLUTTER_NOTIFICATION_CLICK',
'id': '1',
'status': 'done',
'message': title
};
try {
http.Response response = await http.post(Uri.parse('https://fcm.googleapis.com/fcm/send'), headers: <String, String>{
'Content-Type': 'application/json',
'Authorization': 'key=',
},
body: jsonEncode(<String, dynamic>{
'notification': <String, dynamic>{'title': title, 'body': body},
'priority': 'high',
'data': data,
'to': '$token'
})
);
if(response.statusCode == 200) {
print('notification sent');
} else {
print('error');
}
} catch (e) {
print(e);
}
}
I can see on the console that every user has the same token. And even if I alter one token to see if this is the issue, notification is still getting broadcasted to every user instead of a specific user. Am I doing anything wrong?

How to send a scheduled FCM message using the event_time parameter of the FCM Post API? [duplicate]

This question already has answers here:
FCM Schedule delivery date or time of push notification
(2 answers)
How can scheduled Firebase Cloud Messaging notifications be made outside of the Firebase Console?
(2 answers)
Closed 9 months ago.
I want to send a scheduled push notification using firebase messaging from my flutter app.
I use the below code to send a push notification from my app, which works without any issues:
Future<bool> callOnFcmApiSendPushNotifications(String title, String body, List<dynamic> receivers, {String? image = "", String screen = ''}) async {
print('normal message');
List<dynamic> tokens = await pushNotificationsManager.getTokens(receivers);
final postUrl = 'https://fcm.googleapis.com/fcm/send';
Map<String, dynamic> data;
data = {
"registration_ids" : tokens,
"collapse_key" : "type_a",
"notification" : {
"title": title,
"body" : body,
"sound": "default",
"click_action": "FLUTTER_NOTIFICATION_CLICK",
},
'data':{
"title": title,
"body": body,
"click_action": "FLUTTER_NOTIFICATION_CLICK",
"screen": screen,
},
};
final headers = {
'content-type': 'application/json',
'Authorization': authKey
};
final response = await http.post(Uri.parse(postUrl),
body: json.encode(data),
encoding: Encoding.getByName('utf-8'),
headers: headers);
if (response.statusCode == 200) {
return true;
} else {
print(' FCM error');
return false;
}
}
Now for some notifications, I want to send them at 11AM the next day, which I tried to implement using the event_time parameter of the API as per the code below. However, when I try this code, the notification arrives immediately at the receiver, without the required delay.
Future<bool> callOnFcmApiSendDelayedPushNotifications(String title, String body, List<dynamic> receivers, {String? image = "", String screen = ''}) async {
List<dynamic> tokens = await pushNotificationsManager.getTokens(receivers);
// set time to 11AM next day
DateTime dt = DateTime.now();
DateTime dtTomorrow = DateTime(dt.year, dt.month, dt.day+1, 11);
final postUrl = 'https://fcm.googleapis.com/fcm/send';
Map<String, dynamic> data;
data = {
"registration_ids" : tokens,
"collapse_key" : "type_a",
"notification" : {
"title": title,
"body" : body,
"event_time": Timestamp.fromDate(dtTomorrow).millisecondsSinceEpoch.toString(),
"sound": "default",
"click_action": "FLUTTER_NOTIFICATION_CLICK",
},
'data':{
"title": title,
"body": body,
"event_time": Timestamp.fromDate(dtTomorrow).millisecondsSinceEpoch.toString(),
"click_action": "FLUTTER_NOTIFICATION_CLICK",
"screen": screen,
},
};
final headers = {
'content-type': 'application/json',
'Authorization': authKey
};
final response = await http.post(Uri.parse(postUrl),
body: json.encode(data),
encoding: Encoding.getByName('utf-8'),
headers: headers);
if (response.statusCode == 200) {
return true;
} else {
return false;
}
}
I know it is possible to send scheduled push notifications from the Firebase console, but is there any way to send a scheduled notification from the app? Note that I am on a free spark plan so cloud functions cannot be used.
Thanks in advance!

why do not getting notification in ios with firebase_messaging plugin in flutter?

I'm trying to send notification to the android and Ios device as well.
It's working on android devcice but something fishy with ios token , not getting notification on ios devices , I have enabled background notification for ios. In fact it was working before few days ago but suddenly stopped working on ios device. I have updated firebase_messaging plugin but still not getting notification, also visited firebase_messaging issue ,this as well .
I think there is something wrong with my ios token , because I have tested from pushtry website and throw error saying Please check device token , but testing with android token , not getting any errors. so I could say that ios token is not generating properly.
I did everything what I could do but every time got disappointed.
Here's my test Code:
class PUSHTest extends StatefulWidget {
const PUSHTest({Key key}) : super(key: key);
#override
_PUSHTestState createState() => _PUSHTestState();
}
class _PUSHTestState extends State<PUSHTest> {
String token = '';
var serverKey =
'AAAAL4uGYoY:.............................';
#override
void initState() {
super.initState();
getToken();
showAlertNotification();
}
getToken() async {
String t = await FirebaseMessaging.instance.getToken();
print(
"FCM TOKEN: $t");
setState(() {
token = t;
});
}
showAlertNotification() {
FirebaseMessaging.instance
.getInitialMessage()
.then((RemoteMessage message) {
if (message != null) {
print("NOTIFICATIONNNNNNNNNN RESPONSE11${message.data}");
}
});
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
RemoteNotification notification = message.notification;
AndroidNotification android = message.notification?.android;
AppleNotification ios = message.notification?.apple;
print("ios ios ios:$ios");
if (notification != null && android != null && !kIsWeb) {
if (message != null) {
print("NOTIFICATIONNNNNNNNNN RESPONSE22${message.data}");
}
}
});
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
if (message != null) {
print("NOTIFICATIONNNNNNNNNN RESPONSE33${message.data}");
}
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: ElevatedButton(
onPressed: () => sendNotification(),
child: Text("SEND NOTIFICATION"),
),
),
);
}
// My FCM Payload To send notification to the device:
sendNotification() async {
print("send notification button pressed");
try {
http.Response response = await http.post(
Uri.parse('https://fcm.googleapis.com/fcm/send'),
headers: <String, String>{
'Content-Type': 'application/json',
'Authorization': 'key=$serverKey',
},
body: jsonEncode(
<String, dynamic>{
'notification': <String, dynamic>{
'body': 'this is a body',
'title': 'this is a title',
"content_available": true
},
'priority': 'high',
'data': <String, dynamic>{
'click_action': 'FLUTTER_NOTIFICATION_CLICK',
'id': '1',
'status': 'done'
},
'to': token,
},
),
);
if (response.statusCode == 200) {
print("SENT NOTIFICATION TO THE DEVICE :$token");
Fluttertoast.showToast(msg: "SENT NOTIFICATION TO THE DEVICE :$token");
} else {
print("error push notification");
Fluttertoast.showToast(msg: "error push notification");
}
} catch (e) {
print("error push notification");
}
}
}
Okay, finally I found my stupidity, what I exactly did. actually It was 2 major mistakes.
firstly, I used permission_hander and haven't ask for permission for the notification because I was thinking it will be auto ask , when I added remote notification to the plistfile.
secondly, My huge stupidity, I have created 2 firebase project , added configuration file for android (google-service.json) from the another and ios(google-service.plist) from the other projects. and added server-key to the backend from one of them. Nothing wrong with FCM token.
that's why it were working for android only.
Now I have recognised my silliness and deleted duplicate firebase project one, and added configuration file from the original one and updated my server-key to my backend. and also asking permission for notification using permission_handler. That's all.