B4A Library Parse Library – Push Notifications and Cloud Storage

Parse service is shutting down: http://blog.parse.com/announcements/moving-on/

Overview


This library is a rather extensive overhaul of and update to Erels’ original Parse library.

Parse is a company that provides several services for mobile applications and has just been purchased by Facebook so it looks like it should continue to be a stable and reliable service.

You create an account on Parse.com and then create what they call “Applications” which would usually correspond with individual Android applications but don’t have to, so several different Android applications could access a common body of data in a single Parse application. Within Parse applications there are “Classes” of data which look much like a database table and contain ParseObjects which look like an individual row of data in a table.

Capabilities

The two major uses for this library are as follows

1) Providing cloud based data storage and retrieval for data held in the individual Parse Applications in a simple way including querying the stored data. No need to mess with HTTP and networking, it is all done for you in an object oriented fashion.

2) Supporting Push Notifications which can be instigated both from the Parse Web Dashboard of your Parse account and, if you have enabled it in the Dashboard for that Parse application, also from devices running the corresponding Android application. Push Notifications are sent in the context of the individual Parse Applications whose Android applications have registered to receive them but individual devices, or groups of devices, may be selectively targeted by using “Channels”.

Parse offer three levels of service, the first being free as long as you keep within their limits which are one million API Requests per month, one million Push Notifications per month and one Gigabyte of storage use. You can exceed these limits without upgrading to the next paid plan, which is presently 199 US dollars per month if you register a credit card. You can exceed these limits and be charged 7 US cents per one thousand excess API Requests, 20 UC cents per one thousand Pushes and 20 US cents per one Gigabyte of excess storage. There is information on your usage of all three available in your Parse Dashboard.

An API Request is a single network operation which are the ones that raise Basic4android events from the library.

The definition of the number of Pushes is “The total number of push notifications queued for delivery to a client device”. I may be being stupid but that seems ambiguous to me and I don’t understand whether that means that the total number of Push Notifications counts as each single message sent to lots of devices or as the total number of devices to which a single message is sent. I suspect the latter. If anyone knows definitively than please post and I will amend this paragraph.

The amount of storage used is obvious and needs no explanation.

Please read the Parse Android Guide, in the Parse.com Documentation section of their web site, for more information about how to use this library. The Parse Android API document might also be useful occasionally. The mapping of this library objects methods to those of the Java API are usually obvious.

All the operations which need to access the Parse online service are done asynchronously and raise events when complete whose parameters include a Success indication. If an error occurs Success will be False and a ParseException with a message describing the error will be placed in LastException. If necessary this should be processed in the event code as there is a possibility that a further error could occur in another asynchronous call that would overwrite the existing LastException.

Note that these asynchronous operations do not necessarily complete in the order in which they are invoked. To deal with this possibility a TaskID parameter is provided in each call that can be used, if required, to identify which of several possible method calls has just completed.

Installation instructions

In order to use this library you should sign up to Parse.com, go to your Dashboard and create a new Parse application called whatever you feel like calling it. You will need two keys, Application Id and Client Key, which you will find under the Settings for your application. Both are required and need to be copied to the appropriate Process Global variables in the demo.

You also need to download the Parse Android SDK from the Downloads section of the Parse.com web site. Inside the zip file you will find a file named Parse-1.2.4.jar or similar. Copy this to your Additional Libraries folder and rename it ParseNative.jar. Also put Parse.jar and Parse.xml from the demo archive in your Additional Libraries folder.

As detailed in the help for Parse. EnableNotifications in order for your application to receive Push Notifications you need to add the following to the Manifest Editor in your project.
B4X:
SetApplicationAttribute(android:name,"anywheresoftware.b4a.objects.ParseObjectWrapper$ParseApplication")

AddApplicationText(<service android:name="com.parse.PushService" />
<receiver android:name="com.parse.ParseBroadcastReceiver">
  <intent-filter>
    <action android:name="android.intent.action.BOOT_COMPLETED" />
    <action android:name="android.intent.action.USER_PRESENT" />
  </intent-filter>
</receiver>)

Version 1.1 of this library specified the Parse keys in a Parse.Initialize method. This method no longer exists in version 1.2 and later. This is because it it was called from within an Activity, but if Android killed your process and then tried to restart the Parse Service this failed because the service started without the activity being created and so was not initialised correctly. Initialisation now occurs on Application creation and requires the library Application class name to be registered in the manifest and the Parse keys to be specified as an xml resource. When the application is loaded you will see the values in the xml file echoed to the filtered logs.

You also need to place a file called res.xml in your project Objects/res/xml folder and make it read-only. The xml folder does not exist in the project archive but will be created at your first compile. The contents of res.xml should specify your Parse keys as follows
B4X:
<!--?xml version="1.0" encoding="utf-8"?-->
<data>
   <data1 value="YourParseApplicationAppID" />
   <data2 value="YourParseApplicationClientKey" />
</data>

The demo project is already set up to receive push notifications. Try sending one from your Parse Application using the Parse Dashboard.

Run the demo and have a play.

Issues

I have found that using IE10 to send a Push from the Parse Dashboard usually causes the Push to be sent twice, you will see this in the Dashboard list of pushes sent and also at the device and of course they both count towards your free total. Chrome appears to work correctly and sends only one. The work-around is obvious.

The Parse library starts a service called PushService to receive the Pushes and which you can see in Settings -> Apps -> Running -> ParseDemo. Prior to Parse SDK 1.2.4 sometimes this service stopped receiving Pushes and the Process needed to be stopped using a Task Manager and restarted. Parse SDK 1.2.5 should have fixed this.

EDIT:- Version 1.2 now posted. See post #6 for details.

EDIT:- Version 1.3 now posted. See post #13 for details.

EDIT:- Version 1.4 now posted. See post #17 for details.
 

Attachments

  • Parse1.4.zip
    43.2 KB · Views: 1,301
Last edited by a moderator:

adrianstanescu85

Active Member
Licensed User
Longtime User
This is wonderous!!! JUST what I needed, the actual main engine at my fingertips!!!

I do have a question: in the cloud database, the entries are stored with a timestamp each, that's what Parse does, and that field is called "createdAt". It's a date plus time, so a DateTime type.

I want to grab that info for a certain record, but so far I wasn't able to do so, it worked just fine with numbers and strings, but not the Date type.

For instance, I'm successful with:
lbl10.Text = po.GetString("Triaj")

but it doesn't work at all with:
lbl2.Text = po.GetObject("createdAt")

What would be the proper way to extract that date from Parse?? I'd really need this more than anything!

Thank you!
 

agraham

Expert
Licensed User
Longtime User
but it doesn't work at all with:
In what way does it "not work at all"?

EDIT:- Brief information blackout on my part. There are two properties CreatedAt and UpdatedAt which give you the ticks value of the date and time, you can't access those fields in the normal way.
 
Last edited:

adrianstanescu85

Active Member
Licensed User
Longtime User
[EDIT:- Brief information blackout on my part. There are two properties CreatedAt and UpdatedAt which give you the ticks value of the date and time, you can't access those fields in the normal way.[/QUOTE]

That's exactly what I meant, I was refering to those exact properties, but what is a functional ("non-normal") way to access those? This would be really really important!

Thank you!
 

agraham

Expert
Licensed User
Longtime User
Version 1.2 now posted has a different method of initialisation to avoid a problem when Android killed the application process. Please read the first post above which has been amended. The same information is in the readme.txt file in the archive.

The demo is improved to check whether a notification has been processed before. This is necessary because if you dismiss a notification activity then restart it from list of previous apps button it appears as though a notification has just been received because the Activity is given the previous StartingIntent.

The new demo also shows how to parse the data in a push notification.
 
Last edited:

CapReed

Member
Licensed User
Longtime User
This example is just great!

Being able to have a cloud storage for our applications with scalable price, and also have push notifications gives us a lot of power.

I will study the example carefully, I have already installed the libraries and I signed up for parse.com

I have a question, why push notifications to deliver over the dashboard just enter my android when running the app?

Thank you very much for your great and steady job in creating useful examples in B4A :sign0188:
 

CapReed

Member
Licensed User
Longtime User
Sorry my bad English, is by the translator of google ;-)

These are the steps I follow:

1. - I run your example on my mobile phone
2. - From my laptop, I go into the web of parse.com
3. - I cast push notifications from the web
4. - I wait into my mobile phone
5. - Not up anything, keep waiting a few minutes. Nothing arrives
6. - I close your example in the mobile
7. - Again I run your example, and that's when I get the pending notification immediately .

I think it is wrong, it should to get the notification immediately, without having to close the application and reopen it.

Thank you!
 

agraham

Expert
Licensed User
Longtime User
Try waiting longer. There seem to be problems with the Parse Service not maintaining its connection to the Parse Servers. When this happens the Parse Service waits a bit and tries again. Eventually it will get through. You can see this happening in the unfiltered logs. Look out regularly for a new Parse SDK sometime soon. Other people with Android applications are seeing this as well.
 

CapReed

Member
Licensed User
Longtime User
Good night,

I think spend some time after I found solution for the delay time problem.

If the connection of the device is through WIFI delay time can be several minutes.

However, if the connection is through push notifications arrive 3G/GPRS immediately.

Interestingly, with GCM also is exactly the same ....

I hope I can help some other fellow with my experience.
 

RadCoder

Member
Licensed User
Longtime User
it seems that once you include this library and modify the manifest as required, B4a no longer functions as expected. DIP is no longer handled properly(i think its ignored) and other weird behavior. To reproduce, just add an imageview to the demo provided using dip and observe.

Dim iv As ImageView
iv.Initialize("")
iv.Color=Colors.Red

Activity.AddView(iv,50dip,50dip,200dip,200dip)

its weird, but it looks wrong on my SIII

can anyone else confirm DIP problems

update
actually confirmed the bug with more detail. remove this line from the manifest:

SetApplicationAttribute(android:name,"anywheresoftware.b4a.objects.ParseObjectWrapper$ParseApplication")

and the imageview will display properly, of course push wont work

put the line back and dip calculations are messed up
 
Last edited:

RadCoder

Member
Licensed User
Longtime User
Hi still didn't fix it, I wrote my own library and am experiencing the same thing. Like you, I extend application, and the sideeffect is that it seems the b4a density global variable is no longer set properly which of course messes up all dip calculation at runtime. I started another thread addressed to Erel regarding this issue

http://www.b4x.com/forum/basic4andr...xtending-application-oncreate.html#post173093
 
Last edited:

pereskjo

Member
Licensed User
Longtime User
Images?

Nice library.:)
Is it possible seeing a example with images also?
 

uswin4224

Member
Licensed User
Longtime User
Hi agraham, thanks a lot for this library,

I already follow your instruction, sign up in parse, create app, download SDK and rename it into ParseNative.jar ,create res.xml and filled it with my appclientkey and appid,

but I had some error during compiling,
see my screenshot below :



I'm currently still using B4a 2.02, should I update to the latest B4a in order to use this library ?
 

uswin4224

Member
Licensed User
Longtime User
Hi agraham, thanks a lot for this library,

I already follow your instruction, sign up in parse, create app, download SDK and rename it into ParseNative.jar ,create res.xml and filled it with my appclientkey and appid,

but I had some error during compiling,
see my screenshot below :



I'm currently still using B4a 2.02, should I update to the latest B4a in order to use this library ?

Nevermind, this library works like a charm after I update to the latest 2.7 B4a.

Good Job agraham.

I have a question,

Let say, I want to send a push notification to my user, informing an update about my app, how can I send a push notification which when user click on it, it will direct user to the market, using intent ? How can we implement this ?, I read the manual on the parse dashboard it mention about JSON, but cannot quite figure it out yet.

do we type this JSON code in the message field of the dashboard or do we have to implement this in our app code ? Need some guidance here.

Thanks for the wonderful library
:sign0098::sign0188:
 

uswin4224

Member
Licensed User
Longtime User
Nevermind, this library works like a charm after I update to the latest 2.7 B4a.

Good Job agraham.

I have a question,

Let say, I want to send a push notification to my user, informing an update about my app, how can I send a push notification which when user click on it, it will direct user to the market, using intent ? How can we implement this ?, I read the manual on the parse dashboard it mention about JSON, but cannot quite figure it out yet.

do we type this JSON code in the message field of the dashboard or do we have to implement this in our app code ? Need some guidance here.

Thanks for the wonderful library
:sign0098::sign0188:


Finally manage to figure it out myself, This is the code that I used in my app. I modified a bit the module Notification in Agraham demo

B4X:
Sub Activity_Resume   
   Dim title, msg, Alert, Hash, Channel, Action As String
   Dim StartingIntent As Intent
   Dim StartingIntent2 As Intent
   Dim JSON As JSONParser   
   StartingIntent = Activity.GetStartingIntent
   
   JSON.Initialize(StartingIntent.GetExtra("com.parse.Data"))
   Dim DataMap As Map
   DataMap = JSON.NextObject
   Alert = DataMap.Get("alert")
   Hash = DataMap.Get("push_hash")
   Action = DataMap.Get("action")
   Channel = StartingIntent.GetExtra("com.parse.Channel")
   
   ' If you dismiss a notification activity then restart it from list of previous apps button it appears
   ' as though a notification has just been received because the Activity is given the previous StartingIntent.
   ' To check if it is a new notification or one that has alredy been processed we save and check the hash of the push.
   If Hash <> PreviousHash Then
      title = "New Notification"
      PreviousHash = Hash
   Else
      title = "Old Notification"
   End If   
   msg = "Push Notification Received!" & CRLF
   msg = msg & "Channel = " & Channel & CRLF
   msg = msg & "Alert = " & Alert & CRLF
   msg = msg & "Hash = " & Hash & CRLF
   msg = msg & "Action = " & Action & CRLF   
'   Msgbox(msg, title)

   StartingIntent2.Initialize("android.intent.action.VIEW",Action) 'google play link
   StartActivity(StartingIntent2)
End Sub

And then in the dashboard just input JSON code, by set the slider to JSON then insert JSON string, in my case I type this

B4X:
{"title":"YOUR NOTIF TITLE","alert":"YOUR NOTIF MESSAGE BODY","action":"https://play.google.com/store/apps/details?id=your.app.package.name"}

and then just click send notification button, The PN will be sent according to your setting (scheduled or now) and when you click the notification it will start an intent with action according in your JSON string.

The Question is :
If your user uninstall the app, their data will not be deleted in dashboard but you will not be able to send them a PN message.
Is it possible to delete this automatically in the dashboard as soon as they uninstall our app ? how can we achieved this ?

Thanks.
 
Last edited:
Top