I have 2 different cloud functions that send a notification to the device. one is sendNewChatMessageNotification and the other one is sendNewFriendRequestNotification.
How can I get the function name that triggered the onMessage method of the firebaseMessaging instance? because I want to show different messages for the different cloud functions.
final firebaseMessaging = FirebaseMessaging();
firebaseMessaging.getToken().then((tokenVal) {
fcmToken = tokenVal;
firebaseMessaging.configure(
onMessage: (Map<String, dynamic> message) async {
// -----> how can I get the cloudFunctionName ??
if(cloudFunctionName == "sendNewFriendRequestNotification"){
//show friend request notification
}else if(cloudFunctionName == "sendNewChatMessageNotification"){
//show new chat message notification
}
}
You will have to code your function to send that string value in the payload of the message. It will not be sent automatically.
Related
I am trying to push a notification to an IOS flutter app. My flutter main loop looks like this:
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
print(await FirebaseMessaging.instance.getToken());
await FirebaseMessaging.instance.setForegroundNotificationPresentationOptions(
alert: true, // Required to display a heads up notification
badge: true,
sound: true,
);
runApp(MyApp());
}
And the initState() of MyApp() looks like this:
#override
void initState() {
super.initState();
FirebaseMessaging messaging = FirebaseMessaging.instance;
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
print('Got a message whilst in the foreground!');
print('Message data: ${message.data}');
if (message.notification != null) {
print('Message also contained a notification: ${message.notification}');
}
});
}
I can't get any of the FirebaseMessaging streams to work. The onMessage/onMessageOpenedApp/onBackgroundMessage() won' work but if the App is closed I can push notifications. But still none of the above streams will have any content.
I push notifications via this python code:
import firebase_admin
from firebase_admin import credentials
from firebase_admin import messaging
cred = credentials.Certificate("auth.json")
app = firebase_admin.initialize_app(cred)
topic = 'test'
apns_config = messaging.APNSConfig(
payload=messaging.APNSPayload(
messaging.Aps(
mutable_content=False,
sound=messaging.CriticalSound('default')
)
)
)
notification = messaging.Notification(
title="FCM Message",
body="This is a Firebase Cloud Messaging Topic Message!"
)
# See documentation on defining a message payload.
message = messaging.Message(
data={
'score': '850',
'time': '2:45',
},
notification=notification,
#topic=topic,
token="token_of_device",
apns=apns_config
)
response = messaging.send(message, app=app)
print('Successfully sent message:', response)
Is there a way to fix this problem?
Thanks in advance.
To test notifications on IOS you must have:
Mac (to run from XCode), IPhone (will not work on emulator, because it is the politics of apple: "get all the money from user"), apple dev account (100$/year), set up certificates, ask user for permissions and then test on real Iphone device
I have a flutter app that in some point the administrator users can save one publication.
Now I want all users receive a notification when that publication is posted (with it title, description ..etc).
How could I do that with firebase messaging?
I already wrote this code which, if I go to firebase console and generate a example notification, I receive it normally:
class PushNotificationsManager {
PushNotificationsManager._();
factory PushNotificationsManager() => _instance;
static final PushNotificationsManager _instance = PushNotificationsManager._();
final FirebaseMessaging _firebaseMessaging = FirebaseMessaging();
Future<void> init() async {
if(Platform.isIOS){
_firebaseMessaging.requestNotificationPermissions(IosNotificationSettings());
}
_firebaseMessaging.configure(
// Called when the app is in the foreground and we receive a push notif.
onMessage: (Map<String, dynamic> message) async {
print("onMessage: ${message}");
print(message['notification']['body']);
},
// Called when the app has been closed completely and its opened
// from the notification directly
onLaunch: (Map<String, dynamic> message) async {
print("onMessage: ${message}");
},
// Called when the app is in the background and its opened from the notif
onResume: (Map<String, dynamic> message) async {
print("onMessage: ${message}");
},
);
}
In summary, how could I generate a notification (with the title and description created) to all users when the admin creates a new publication without going to firebase console to generate it manually?
I'm using firebase_messaging: ^7.0.3
Update
I tried to do this:
Future sendNotification() async {
final String url = 'https://fcm.googleapis.com/fcm/send';
var token = await _firebaseMessaging.getToken();
var data;
data='{"notification": {"body": "this is a body", "title": "this is a title"}, "priority": "high", "data": {"click_action": "FLUTTER_NOTIFICATION_CLICK"}, "to": "${token}"}';
final response = await http.post(
url,
headers: <String, String>{"Content-Type": "application/json", "Keep-Alive" : "timeout=5", "Authorization" : "key=${mykey}"},
body: data
);
print(response.body);
}
...calling this in the method I save the event in firebase only displays the notification to my phone, and not to every phone, there's a way to do it in this form?
You can do this using a cloud function. Either by calling the function from your app when the publication is created, or by having the cloud function listen for a new document. See this Medium post for some ideas: https://medium.com/#jerinamathews/send-firebase-cloud-messaging-fcm-to-a-topic-using-cloud-function-when-realtime-database-value-fa78fa758549
Update
Based on your update, I suggest you look at using a 'Topic' rather than a specific token (that applies to only one device). To use a Topic you need to ensure all users automatically subscribe to the chosen topic when they open the app (they can subscribe to the same topic each time, it has no negative impact). FCM maintains a list of subscribed device tokens against the topic.
I haven't used topic via an http post so I cannot confirm it is possible but I am assuming if you can send to a token you must be able to send to a topic.
I have a cloud function newMessage to listen on any onCreate() event in firebase realtime database. When the newMessage function is triggered, it will get the snapshot of the message content, and use mailgun to send email notification for the new message.
pseudo code is like:
exports.newMessage = functions.database
.ref('/privateMessages/{userA}/{userB}/{messageId}')
.onCreate((snap, context) => {
let senderEmail, receiverEmail, messageContent;
// 1. get message senderEmail, receiverEmail and messageContent from the snap and context.
// 2. use mailgun to send email to receiverEmail for the new message
let data = {
from: senderEmail,
to: receiverEmail,
subject: 'New Message from Freebies',
text: messageContent
};
mailgun.messages().send(data, (error, body) => {
console.log(body);
});
})
return null;
})
My concern is if user is flooding the chat messages, from the newMessage, it will send email every time there comes a new message. On receiver's side, it would be annoying if there are too many email notifications in the inbox. So my question is that is it possible to have multiple onCreate() to get multiple new messages, say within 1 hour, and send only 1 email message for those new messages?
I have a Flutter app that uses Firebase messaging to delivery notifications.
This is the base code, it does nothing special, besides saving the token on my DB.
FirebaseMessaging _firebaseMessaging = new FirebaseMessaging();
_firebaseMessaging.configure(
onMessage: (Map<String, dynamic> message) {
},
onResume: (Map<String, dynamic> message) {
},
onLaunch: (Map<String, dynamic> message) {
},
);
_firebaseMessaging.getToken().then((token) {
saveToken(token);
});
Do I have to implement some kind of background service to keep saving the new token on my DB everytime it gets refreshed? I remember using onTokenRefresh() on Android(JAVA) to do this, but I found nothing about it in Flutter (DART).
I read somewhere that the token gets refreshed every 3600 seconds. I wonder if this is true.
No, FCM token doesn't refresh every 3600 seconds. It only refreshes when :
When user Uninstall/Reinstall the app or Clears App Data
You manually delete FCM Instance using FirebaseMessaging().deleteInstanceID()
You can listen to token refresh stream using:
FirebaseMessaging().onTokenRefresh.listen((newToken) {
// Save newToken
});
Hope it helps
You can use firebaseMessaging.onTokenRefresh to get a stream which receives an event each time a new token is received.
Here is an example of subscribing to the firebaseMessaging.onTokenRefresh stream and updating the token if the token has changed:
FirebaseMessaging().onTokenRefresh.listen((token) async {
final prefs = await SharedPreferences.getInstance();
final String firebaseTokenPrefKey = 'firebaseToken';
final String currentToken = prefs.getString(firebaseTokenPrefKey);
if (currentToken != token) {
print('token refresh: ' + token);
// add code here to do something with the updated token
await prefs.setString(firebaseTokenPrefKey, token);
}
});
You can try with this.. as per new updation
FirebaseMessaging.instance.onTokenRefresh.listen((newToken) {
// Save newToken
});
After the user logs in my app logs her in again automatically every 3500 seconds.
I used a Timer like this:
void _timerPressed() {
const timeout = const Duration(seconds: 3500);
new Timer.periodic(timeout, (Timer t) => _handleSignIn());
}
I set the timer in the 'login' button press method after the login has occurred:
void _loginPressed() {
print('The user wants to login with $_email and $_password');
_handleSignIn()
.then((FirebaseUser user) => print(user))
.catchError((e) => print(e));
_timerPressed();
}
(Don't be fooled by the name of the method, '_timerPressed'. I used a button press for testing the technique and haven't gotten around to renaming the method after I tied it in to the login button.)
Using Flutter for the first time and have implemented Firebase Cloud Messaging. I can sent a notification from Notification Composer in the Firebase Console. I can see in the debug-console on Android whilst the app is in foreground that it receives the data I have set in Custom Data.
_firebaseMessaging.configure(
onMessage: (Map<String, dynamic> message) {
print('on message $message');
},
However I am wondering how to get not only the Custom Data but also the Message Text and Message Title.
if you are trying to get the string for title and body that comes in the message object, you can do something like this:
final title = message['notification']['title'] ?? '';
final body = message['notification']['body'] ?? '';