question about implementing server code

Hi,
I am trying to add server side code for my iOS app. I’v succeeded adding users service event handler and custom event handler, however, there’s problem adding handler for data table.

I get below error when running data table server code.

argument type mismatchjava.lang.IllegalArgumentException: argument type mismatch

I looked at the below link, but it’s different issue - I don’t use REST nor date
http://support.backendless.com/t/correct-usage-of-beforecreate-event-handler-in-data-api

To find if it’s mapping issue, I created very simple temporary Test table which has only 1 custom field of type STRING. There no problem with below code if I remove server code “afterCreate Test table”.
I’ve attached server code files except for bootstrap.java.
bootstrap.java contains Backendless.Persistence.mapTableToClass( “Test”, Test.class );

Test* entity = [[Test alloc] init];
entity.str = @“sdfs”;
[[backendless.persistenceService of:[Test class]] save:entity response:^(Test* newEntity)
I have attached server code files.

Few other questions.
I am creating “before create” event for checking unique identity of entity as suggest in below link
http://support.backendless.com/t/unique-values-and-primary-key-for-column-wihtin-database

  1. How do I actually implement above identity check code. Unlike custom event, I can not return anything, then how can client program know that it failed due to same identity. The below is what I have, if you could provide example, that would be great.

public void beforeCreate( RunnerContext context, ChatGroup chatgroup) throws Exception

{
String groupName = chatgroup.getName();
BackendlessDataQuery dataQuery = new BackendlessDataQuery();
dataQuery.setWhereClause( “name=’”+groupName+"’");

BackendlessCollection<ChatGroup> result = Backendless.Data.of( ChatGroup.class ).find(dataQuery);
if(result.getData().size()==0) //create new entity only the same identity does not exist
super.beforeCreate(context, chatgroup);
}
I have no idea except for not calling super.beforeCreate to prevent new creation.
Do I need to call parents function? For user service handler, not calling super.afterLogin still works.

  1. Business logic execution time for Cloud Enterprise Plan is 120 seconds. If I have “beforeCreate” function implemented on the server, does it mean that actual creation time will be less than 120 sec even if the call is synchronous call? I wouldn’t receive response for 120 seconds?

Direct invocation of custom server-side code takes 120 sec as well?

Regards,
Scott

files.zip (28.53kB)

Hi Scott!

A lot of questions in one post!)

Have you tested this problem (argument type mismatch) with other clients (for example, via rest console)?

  1. Just throw new BackendlessException. For example:
if(result.getData().size() > 0)
 throw new BackendlessException(“Chat group already exists");
  1. Cloud Enterprise Plan is 120 seconds - it means if your custom server code takes more than120 seconds - server will returns timeout error.

Regards,
Kate.

Hi Kate,

Thanks for reply.
I tested with iOS device, using REST API instead of iOS SDK, and it works!
I will change my codes(ones that invokes server side code) to use REST.
If I find need for using iOS SDK or any problem occurs I will get back to you.

Thanks & Regards,
Scott

Hi Kate,

With help from Slava, I’ve managed to send push notification from iOS device.
On some cases I send notification from server code.
I implemented server code to send push notification after create data table entity.
Running the code, I get the following message.

“User has no permission to publish message”
I think it’s another ACL issue, just like the file download problem from my previous question.
I’ve attached source code and capture of channel permission settings.

I enabled role permission of Publish HTTP Post for NotAuthenticatedUser.
Message is delivered without error, but push isn’t sent, the below is message status printed from server code.

MessageStatus{messageId=‘DE58F927-653E-7525-FF2C-523AD41D9C00’, status=PUBLISHED}

The code for sending push notification on server side is exactly the same as one that I used on iOS client.

For iOS

-(void)publish:(NSString *)channelName message:(id)message publishOptions:(PublishOptions *)publishOptions deliveryOptions:(DeliveryOptions *)deliveryOptions response:(void(^)(MessageStatus *))responseBlock error:(void(^)(Fault *))errorBlock;

which is equivalent to

public com.backendless.messaging.MessageStatus publish(java.lang.String channelName, java.lang.Object message, com.backendless.messaging.PublishOptions publishOptions, com.backendless.messaging.DeliveryOptions deliveryOptions)

Regards,
Scott

upload.zip (61.4kB)

Hi Scott!

Just to clarify:
In this app push notifications sending and receiving works properly if publish them via ios sdk?
You have problems just with server code?

Hi Kate
In this app push notifications sending and receiving works properly if publish them via ios sdk?

Push notification sent through backendless iOS SDK can be received by the receiver.

You have problems just with server code?
Yes problem only with server code.
Push notification sent through server code using java sdk (backendless.jar) CAN NOT be received by the receiver.

Just to make sure you that you know, it has ACL problem as I wrote previously.
“User has no permission to publish message”

Thanks

  1. According to the ACL problem:
    you try to publish message from server code as NotAuthenticated user.
    Thats why this error message is correct.
    You can add some admin user, GRANT “publish” permission for him and
    login admin user in server code before publishing.

  2. I will check problem with receiving push notifications. It will take some time.

Hi Kate,

Any updates?

I have simple question to ask.
Setting server code event handler to async from console, does that mean your web server will respond immediately to a http request, and server code will be executed anytime after http request has been received by the server?

Regards,
Scott

Hi Scott!

  1. Yes, all is correct.
  2. Our development team is working on this problem (push notification issue).

Regards,
Kate.

Hi Kate,

Thanks for all the help so far!

I’m almost done migrating Backendless from previous baas I used.
There’s one problem, and regarding this problem, I sent email to Mark yesterday, but I thought that he might be busy or may not have received my mail so I am writing in.

I totally understand that fixing “sending push by server API” problem will take some time. I just want to know how much time it will take - if it takes weeks to fix, I will use iOS client SDK for sending push.
The thing is that I found some problem sending push with backendless iOS SDK. I don’t think it’s a iOS SDK problem, but rather backendless push server issue and iOS7/8 support issue.

  1. sending push with data more than 256 bytes
    From iOS 8, push message size is 2 kilobytes max, but as I tested sending push using iOS 8 devices, it fails with error “length greater than 256”. I guess your server does not support iOS 8. I can limit the length of text that’s no problem.
    The real problem comes after getting size limit error - whenever I try to send from a device A to device B, it fails with error “Socket Closed” for many times. I tried sending from B to A, but it fails with the same error. I wasn’t able to send push for while, something like 15 min. I actually had some “socket error” before, back then I sent message from console, not lengthy ones though.
    As push notification is critical feature, is it possible to stablize push server? (exception handling, socket reconnect, etc)

  2. Receiving data in background mode
    Unlike android device, there’s no way to receive push notification when the app is in background mode prior to iOS 7.

For iOS 7+, apple introduced silent push notification, which made possible for app to receive push notification when the app is in background mode.
If you take a look at below Apple document, it’s “content-available” APNS field that needs to be added when sending push to apple server.
Can you add this feature?

https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/ApplePushService.html

Thanks & Regards,
Scott

Hi Scott!

Thank you for this message too!
You say
I totally understand that fixing “sending push by server API” problem will take some time… >>
you mean sending push messages from server code? Yes?
Currently I cannot say how much time it will take.
I will notify you tomorrow, ok?

  1. sending push with data more than 256 bytes >> currently we are working on these problems.
  2. Receiving data in background mode >> yes, we will add this feature in a few next days.
    It will take several days to implement new feature and to check bug fixes.

Regards,
Kate.

Hi Kate,

Thank you so much for quick reply!

I am sorry if I bugged you and your team too much.
It’s just that I was kind of nervous about the fact that I spent almost 3 weeks, migrating from different BaaS, may not release my app soon due to push notification issue. Apple reserves app name for only 6 months and I only have a week to finish before losing my app name, then I would have to redesign icons, screenshot, website, etc. I hope you understand.

Using the service for several weeks, I truly think that Backendless is the best out of all the BaaS’ I used so far. It would’ve been a lot better if I had known about Backendless earlier.
I really appreciate your support.

Best,
Scott

Hi, Scott,

You need to specify the recipients of your push notification. In order to do that, you can add the following line:

deliveryOptions.setPushBroadcast( PushBroadcastMask.ALL );

In this case your push notification will be received by all devices, registered to the channel you specified as the first argument in your Backendless.Messaging.publish( … ) method call.

You can also send push notification only to Apple devices:

deliveryOptions.setPushBroadcast( PushBroadcastMask.IOS );

or to Android devices:

deliveryOptions.setPushBroadcast( PushBroadcastMask.ANDROID );

or to Windows Phone devices:

deliveryOptions.setPushBroadcast( PushBroadcastMask.WP );

Or you can send your push notification to some specific list of devices, identified by their registration IDs, using the following method:

deliveryOptions.setPushSinglecast( List&lt;String&gt; deviceRegistrationIDs );

If you specify neither pushBroadcast, nor pushSinglecast, then the message is published, but not delivered to any device.

Regards,
Sergey

Thanks Sergey.

It works now!
I thought there’s a bug because push is sent using iOS SDK without setting pushBroadcast.

Regards,
Scott

Yes, in iOS SDK the DeliveryOptions.pushBroadcast = IOS by default, so iOS devices can receive the push notification without any setting for it.

Now about the features “Push notifications don’t maintain the “content-available” key of notification payload” & “Push notifications don’t maintain the “alert” with size more then 256 symbols (2K is allowed)”: they were fixed, QA yet will check them, so they will be deployed on the production in the beginning next week.