I have a chat app using Google cloud messaging. I have to migrate to FCM because of API Key. I used this tutorial: GCM to FCM but When I start the app, it closes immediately.
This is the part of Gcmintentservice. I didn't understand what I should make
Gcmintentservice.
protected void onHandleIntent(Intent intent) {
String key = intent.getStringExtra(KEY);
switch (key) {
case SUBSCRIBE:
// subscribe to a topic
String topic = intent.getStringExtra(TOPIC);
subscribeToTopic(topic);
break;
case UNSUBSCRIBE:
String topic1 = intent.getStringExtra(TOPIC);
unsubscribeFromTopic(topic1);
break;
default:
// if key is not specified, register with GCM
registerGCM();
}
}
When I delete inside of onHandleIntent function, App is working and there is no error but instant messaging is not working.
Related
I have implemented SMS Retriever on Xamarin Android based on examples such as this and this. Everything works fine as expected EXCEPT the message I am assuming to be intercepted by BroadcastReceiver class (see below) also shows up in the Messages app (where SMS messages show up).
I am using Attributes with the BroadcastReceiver class (see below) instead of doing the equivalent in AndroidManifest.xml.
SmsRetriever object is initialized in MainActivity Create() method and activated as var smsRetriever = SmsRetriever.GetClient(this.ApplicationContext); and smsRetriever.StartSmsRetriever();
My App is using Twilio's Programmable SMS API to send OTP code terminated with an App Hash string on new line, as specified for SMS Retriever API. This works as expected except for the SMS message showing in Messages app.
I also used another phone to send the code, and it works in exactly the same way as Twilio server as above.
Question: Is the message showing up in the Messages app as intended and therefore unavoidable, or am I missing something to have the SMS message suppressed in Messages app?
I am assuming that the SMS Retriever API, having detected the App Hash String, will only forward the SMS message to the BroadcastReceiver and not forward to the Messages app (which at best is pointless to be displayed there).
[BroadcastReceiver(Enabled = true, Exported = true)] [IntentFilter(new[] { SmsRetriever.SmsRetrievedAction })]
public class SmsBroadcastReceiver : BroadcastReceiver
{
public SmsBroadcastReceiver() { }
public override void OnReceive(Context context, Intent intent)
{
if (intent.Action != SmsRetriever.SmsRetrievedAction) return;
var extrasBundleundle = intent.Extras;
if (extrasBundleundle == null) return;
var status = (Statuses)extrasBundleundle.Get(SmsRetriever.ExtraStatus);
switch (status.StatusCode)
{
case CommonStatusCodes.Success:
// Get SMS message contents
var messageContent = (string)extrasBundleundle.Get(SmsRetriever.ExtraSmsMessage);
// Extract one-time code from the message and complete verification
// by sending the code back to your server.
...
break;
case CommonStatusCodes.Timeout:
...
break;
case CommonStatusCodes.NetworkError:
...
break;
case CommonStatusCodes.Interrupted:
...
break;
case CommonStatusCodes.InternalError:
...
break;
default:
...
break;
}
}
The SMS is just like another normal message. So it will show up in the Messages app. SMS retrieval API built just to verify devices.
I'm using FireBase Cloud Messaging in Unity. I want to open a link when the user clicks on the arrived message from FireBase Cloud Messaging.
In Firebase panel I set custom data "click_action" with a URL value to message, and I receive it when clicking on notification in OnMessageReceived method like :
public void OnMessageReceived(object sender, Firebase.Messaging.MessageReceivedEventArgs e)
{
Debug.Log("Received Data: " + e.Message.Data["click_action"]);
}
When I add code like
Application.OpenURL(e.Message.Data["click_action"]);
in OnMessageReceived, the link opens but the application also will open when taping on received notification.
How can prevent application to open when clicking on FCM message in Unity?
Thanks.
Have you try the ACTION_VIEW Intent?
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
String message = remoteMessage.getData().get("click_action");
String url = "http://your.url.here";
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(url));
startActivity(i);
}
The FirebaseMessagingService has the method onMessageReceived() which we should override to handle notifications, but this only works when the app is in Foreground.
To handle notifications even when the app is in background, I used to override the handleIntent, to just call the onMessageReceived().
In FirebaseMessagingService 11.6.0, the method handleIntent became final, with that said, I can't override it as I was doing.
How should I handle notifications when my app is in background in the 11.6.0?
public class NotificationsListenerService extends FirebaseMessagingService {
private static final String TAG = "NotificationsListenerService";
#Override
public void onMessageReceived(RemoteMessage remoteMessage)
String notifyData = remoteMessage.getData().get("notifData");
if(notifyData.contains("|")){
String[] itens = notifyData.split("\\|");
notifyData = itens[0];
}
String notifyType = remoteMessage.getData().get("notifType");
String title = remoteMessage.getData().get("title");
String message = remoteMessage.getData().get("body");
if(!isAppInForeground(App.getContext())){
sendNotification(title, message, notifyData, notifyType);
}
}
#Override
public final void handleIntent(Intent intent) {
...
this.onMessageReceived(builder.build());
...
}
private void sendNotification(String messageTitle, String messageBody, String notifyData, String notifyType) {
...
}
//Detect if app is in foreground
private boolean isAppInForeground(Context context) {
...
}
}
It's not intended for anyone to override handleIntent(). That's why it was made final. Also, you'll notice that it's completely missing from the javadocs - that's intentional.
If you want to handle a message in any circumstance (both foreground and background), use onMessageReceived(). The javadoc for that method says:
Called when a message is received.
This is also called when a notification message is received while the
app is in the foreground. The notification parameters can be retrieved
with getNotification().
This should work for data messages, but not notification messages sent from the console. Notification messages have different delivery behavior. See the documentation about message types and how to handle them.
I'd add that in FirebaseMessagingService 11.8.0 docs, it is stated in https://firebase.google.com/docs/cloud-messaging/android/receive that if a notification has a data payload it will call onMessageRecieved() when the app is in the foreground, and if the app is in the background the notification and data payload are delivered in the extras of the intent of your launcher Activity.
So, this means you need to decide how to handle the notification in two places, depending on whether the user is actively using the app or if it is in the background.
As you have seen yourself, if you receive the notification while the app is in the foreground, onMessageReceived() is called and you handle the notification there.
When the app is launched from the background, you have 2 options:
1: By default, the notification is sent to your system tray, and when it is clicked it opens your main activity, passing the data (what would have been remoteMessage.getData() in onMessageReceived()) to your activity as intent extras. You can handle the extras in your main activity like so and decide what to do with them, for instance check for a key value and launch a related intent.
// [START handle_data_extras]
if (getIntent().getExtras() != null) {
for (String key : getIntent().getExtras().keySet()) {
Object value = getIntent().getExtras().get(key);
Log.d(TAG, "Key: " + key + " Value: " + value);
}
}
You can decide what intent to open on-click if you add an intent-filter in your app manifest and a designated "click_action" value in your notification, and then handle the intent extras in the designated activity. See https://stackoverflow.com/a/39665485/3746204
I'd also suggest checking the firebase messaging sample app for ideas: https://github.com/firebase/quickstart-android/tree/master/messaging
i have the same problem after update firebase library version.
i think the easiest way is downgrade firebase library again (i use 11.4.2) and handleIntent() still works !
I'm using intercom.io to send messages to my customers. I can receive gcm (with notification) from intercom just fine, ONLY if the message that I sent is the first message in a conversation. For subsequent messages in the conversation, I don't receive anything. I put a log in my onMessageReceived() but it didn't receive anything, except if the message is the first message in a conversation.
public class MyGcmListenerService extends GcmListenerService {
#Override
public void onMessageReceived(String from, Bundle data) {
MessageUtils.log("onMessageReceived data is " + data);
}
}
Any idea what am I missing?
In case you don't get what I'm trying to say, here's what I meant:
I select a customer from my intercom.io web dashboard (or
whatever it's called)
Then I click on the 'Message' button to
send a message to the customer.
The customer received my message, together with the notification.
Now I send another message to the customer within the same conversation as before.. but now the customer won't receive any more gcm message from intercom.
Yes it does support now. The github issue is closed now and they added it in 3.0.3
They have a git hub project for FCM, but it is missing few code.
The code is available on this github page and is as follows
if you are extending FirebaseMessagingService in a class in your own app? then you will need to manually pass on the push to intercom now.
private final IntercomPushClient intercomPushClient = new IntercomPushClient();
public void onMessageReceived(RemoteMessage remoteMessage) {
Map<String, String> message = remoteMessage.getData();
if (intercomPushClient.isIntercomPush(message)) {
intercomPushClient.handlePush(getApplication(), message);
} else {
//DO HOST LOGIC HERE
}
}
I have 2 service (Service A and B) that exchange data using binding. One of the 2 services (Service A) can bind to multiple services (now there is only Service B, but I'll have to add also other 2 services, C and D). All the services exchanges data in the same way and use the same messages.
I would like to know if it is possible to retrieve the name of the service that sent the message.
In particular my Service A when receives a message from B needs to store this information so when it receives the same message from C or D behaves differently. Is it possible without adding a String in a bundle attached to the Message?
This is the code where I would like to get this info in Service A
class myHandler extends Handler {
#Override
public void handleMessage(Message msg) {
String senderName;
switch (msg.what) {
case REGISTER:
senderName = ???
addToRecord(senderName);
sendConfirm(msg.replyTo, SUCCESS);
break;
case UNREGISTER:
senderName = ???
removeFromRecord(senderName);
sendConfirm(msg.replyTo, SUCCESS);
break;
default:
super.handleMessage(msg);
}
}
}
Message's structure like :
Message{
what,arg1,arg2,obj,when,data,replyTo.
}
and Bind of Messenger :
oneway interface IMessenger {
void send(in Message msg);
}
So your background service can not obtain the name of original service.
As you said, putting a String in a bundle to the message can resolve this.
In some circumstances for avoid fake name, you can assign the particular String to the original service when binding. And let them resend to your service when call the remote method.