Sending custom push using server code

Hi, I am trying to send a push notification through server code, however it doesn’t seem to work correctly:

Server Code:

private String sendMessage(int type,String from,String recipient,String msg_content,byte[] img_bitmap,String geo_lat,String geo_long,String address,String cvs_name,String cvs_phone,byte[]cvs_bitmap) {
        String whereClause = this.user_field + " = '" + recipient + "'";
        BackendlessDataQuery query = new BackendlessDataQuery(whereClause);
        BackendlessCollection<BackendlessUser> users = Backendless.Data.of(BackendlessUser.class).find(query);
        String deviceToken = "";
        if (users.getData().size() > 0) {
            deviceToken = users.getData().get(0).getProperty("currentDeviceId").toString();
        }
        System.out.println("deviceid = "+deviceToken);
        List<String> devices = new ArrayList<>();
        devices.add(deviceToken);
        DeliveryOptions deliveryOptions = new DeliveryOptions();
        deliveryOptions.setPushSinglecast(devices);
        PublishOptions publishOptions = new PublishOptions();
        publishOptions.putHeader( "android-ticker-text", "New cartow message" );
        publishOptions.putHeader( "android-content-title", "New cartow message" );
        publishOptions.putHeader( "android-content-text", "test" );
        publishOptions.putHeader("type", String.valueOf(type));
        publishOptions.putHeader("from",from);
        publishOptions.putHeader("time", String.valueOf(System.currentTimeMillis()));
        switch (type){
            case 0:
                publishOptions.putHeader("msg_content", msg_content);
                break;
            case 1:
                publishOptions.putHeader("img_bitmap", String.valueOf(img_bitmap));
                break;
            case 2:
                publishOptions.putHeader("geo_lat",geo_lat );
                publishOptions.putHeader("geo_long", geo_long);
                publishOptions.putHeader("address", address);
                break;
            case 3:
                publishOptions.putHeader("cvs_name", cvs_name);
                publishOptions.putHeader("cvs_phone", cvs_phone);
                publishOptions.putHeader("cvs_bitmap", String.valueOf(cvs_bitmap));
                break;



        }
        MessageStatus status = Backendless.Messaging.publish("cartownmessage", publishOptions, deliveryOptions);
        System.out.println("message sent");
        return String.valueOf(status.getStatus());



    }

Custom Reciever:

public class PushReceiver extends BackendlessBroadcastReceiver {
private long notification_id = 0;
private WiChatDB LocalDatabase;
@Override
public void onError(Context context, String message) {
super.onError(context, message);
Log.i("PushReciever","error: "+message);
}
@Override
public boolean onMessage(Context context, Intent intent) {
HashMap arguments = new HashMap();
int type = Integer.parseInt(intent.getStringExtra("type"));
String senderId = intent.getStringExtra("from");
String time = intent.getStringExtra("time");
arguments.put("type",type);
arguments.put("from",senderId);
arguments.put("time",time);
LocalDatabase = new WiChatDB(context, Utils.getUsername());
switch (type){
case 0:
String msg_content = intent.getStringExtra("msg_content");
notification_id = LocalDatabase.addMessage(3,senderId,time,false,false,msg_content);
arguments.put("msg_content",msg_content);
break;
case 1:
byte [] img = intent.getStringExtra("img_bitmap").getBytes();
notification_id = LocalDatabase.addImage(4,senderId,time,false,false,img);
break;
case 2:
String geo_lat = intent.getStringExtra("geo_lat");
String geo_long = intent.getStringExtra("geo_long");
String geo_address = intent.getStringExtra("address");
GeoPoint point = new GeoPoint();
point.setLatitude(Double.parseDouble(geo_lat));
point.setLongitude(Double.parseDouble(geo_long));
notification_id = LocalDatabase.addLocation(5,senderId,time,false,false,point,geo_address);
arguments.put("geo_address",geo_address);
break;
case 3:
String cvs_name = intent.getStringExtra("cvs_name");
String cvs_phone = intent.getStringExtra("cvs_phone");
byte[] cvs_bitmap = intent.getStringExtra("cvs_bitmap").getBytes();
notification_id = LocalDatabase.addContact(7,senderId,time,false,false,cvs_name,cvs_phone,cvs_bitmap);
arguments.put("cvs_name",cvs_name);
arguments.put("cvs_phone",cvs_phone);
break;
}
sendNotification(context,arguments);
return false;
}
private void sendNotification(Context ctx, HashMap args) {
if(new WiChatSharedPreferences(ctx).isSettings_allow_notifications()){
Intent intent = new Intent(ctx, MainActivity.class);
intent.putExtra("isNotification",true);
intent.putExtra("goToChat",true);
intent.putExtra("senderId",args.get("from").toString());
String title = ctx.getResources().getString(R.string.new_message);
String message = "";
WiChatSharedPreferences preferences = new WiChatSharedPreferences(ctx);
switch ((int) args.get("type")){
case 0:
if(preferences.isSettings_display_private_notifications())
message = ctx.getResources().getString(R.string.info_msg,args.get("from").toString(),args.get("msg_content").toString());
else message = ctx.getResources().getString(R.string.info_msg_private);
break;
case 1:
if(preferences.isSettings_display_private_notifications())
message = ctx.getResources().getString(R.string.info_img,args.get("from").toString());
else message = ctx.getResources().getString(R.string.info_msg_private);
break;
case 2:
if(preferences.isSettings_display_private_notifications())
message = ctx.getResources().getString(R.string.info_location,args.get("from").toString());
else message = ctx.getResources().getString(R.string.info_msg_private);
break;
case 3:
if(preferences.isSettings_display_private_notifications())
message = ctx.getResources().getString(R.string.info_contact,args.get("from").toString());
else message = ctx.getResources().getString(R.string.info_msg_private);
break;
}
//int notification_id=0;
//intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(ctx, 0 /* Request code */, intent, PendingIntent.FLAG_ONE_SHOT);
Bitmap bm = BitmapFactory.decodeResource(ctx.getResources(), R.mipmap.ic_launcher);
if(LocalDatabase.getChatListByUsername(args.get("from").toString()).getBitmap()!=null){
LocalDatabase.getChatListByUsername(args.get("from").toString()).getBitmap();
}
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(ctx)
.setSmallIcon(R.mipmap.ic_launcher)
.setLargeIcon(bm)
.setContentTitle(title)
.setContentText(message)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) ctx.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify((int) this.notification_id /* ID of notification */, notificationBuilder.build());
}
}
}

Manifest

<receiver android:name=".services.PushReceiver" android:permission="com.google.android.c2dm.permission.SEND">
    <intent-filter>
        <action android:name="com.google.android.c2dm.intent.RECEIVE"/>
        <action android:name="com.google.android.c2dm.intent.REGISTRATION"/>
        &lt;category android:name=&quot;net.crofis.wichat&quot;/&gt;
    &lt;/intent-filter&gt;
&lt;/receiver&gt;

Hi!

Can you clarify please the following questions:

  1. What do you mean under “it doesn’t seem to work correctly”?
  2. Have you tried to debug your client code to find out if the message is received to the device?
  3. Do you have problems with notifications sent from console or another device?
  4. Check out the sending message if it really contains needed deviceId.
    best regards,
    Alex

What I meant by “It doesn’t seem to work correctly” is that there is something that I am doing wrong either with the server code or with the client.

I was able to send a push notification to a specific device using the console and using the default BroadcastReciever. My custom receiver was also invoked whenever I tried that. This leads me to believe that I am doing something wrong in the server code but I just don’t know where and what is it that I am missing.

If you look at the server code I included you can see its set to 3 different stages:
Line 2~11 - get the current device id by username.
Line 12~38 - build the message.
and Line 40 - send the message.

I have debuged the server code with CodeRunner and it seems to work however it does not invoke neither my custom receiver nor BackendlessBroacastReciever.

I’ve noticed that you don’t set channel in your custom code. Are you using “default” channel only?

Also, have you tried to debug the client code? Maybe, message is received, but fails somewhere inside and notifying is not triggered.

So I did some experimentation with the console:
This worked:
“android-ticker-text”:“test”,“android-content-title”:“test”,“android-content-text”:“test”
This didn’t:
“android-ticker-text”:“test”,“android-content-title”:“test”,“android-content-text”:“test”,“type”:“0”,“from”:“minitour”,“time”:“1463748199776”,“msg_content”:“hello world”

The first header was able to invoke my custom receiver, the second one however did not.

UPDATE:
I removed the following code and it worked (onMessage is now being invoked), however this is still a problem for me since I need to send custom data within the push:

publishOptions.putHeader("type", String.valueOf(type));
publishOptions.putHeader("from",from);
publishOptions.putHeader("time", String.valueOf(System.currentTimeMillis()));
switch (type){
    case 0:
        publishOptions.putHeader("msg_content", msg_content);
        break;
    case 1:
        publishOptions.putHeader("img_bitmap", String.valueOf(img_bitmap));
        break;
    case 2:
        publishOptions.putHeader("geo_lat",geo_lat );
        publishOptions.putHeader("geo_long", geo_long);
        publishOptions.putHeader("address", address);
        break;
    case 3:
        publishOptions.putHeader("cvs_name", cvs_name);
        publishOptions.putHeader("cvs_phone", cvs_phone);
        publishOptions.putHeader("cvs_bitmap", String.valueOf(cvs_bitmap));
        break;


}

Obviously, the problem is about extra headers. Have you tried to debug your onMessage() method to find out where exactly it fails?

I really have no clue what caused this but its now working, also important to note I changed the following header:

publishOptions.putHeader("from",from);

To:

publishOptions.putHeader("sender",from);

This is apparently being used by backendless but that’s not what caused the issue previously.

It’s nice that you’ve got it working.

Anyway, we shall try to find out what caused the problem.