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,294
Last edited by a moderator:

Vincenzo Fabiano

Member
Licensed User
Longtime User
check your manifest ....and premissions of parse notification..

I have this on manifest:

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>)
 

monadhl

Member
Licensed User
Longtime User
I did all the steps and the result is always wrong
Is there a solution?
 

Attachments

  • 1.png
    1.png
    5 KB · Views: 240
  • 2.png
    2.png
    29.1 KB · Views: 241
  • 3.png
    3.png
    52.9 KB · Views: 232
  • 4.png
    4.png
    127.6 KB · Views: 247
  • 5.png
    5.png
    37 KB · Views: 239

omidaghakhani1368

Well-Known Member
Licensed User
Longtime User
Hi.
I ask question about get delivery clicking notification already but anyone not help me.
Please guide me
I send 200 message from parse.com to devices
How detect user click on notification or delivery?
 

staplman

New Member
Licensed User
Longtime User
The new version of the API 1.7 or higher still crashes the app on launch, clearly there are a lot of people here experiencing this.

is there a fix for it yet?
 

imgsimonebiliato

Well-Known Member
Licensed User
Longtime User
Also me, the app crash.
Please, is there a fix?
 

msawada

Member
Licensed User
Longtime User
The source is attached. If possible please upload your changes when they are ready.
Hi Erel: Any chance you could provide a zipped complete eclipse project with the parse source? I am trying to add one of the parse.com android sdk methods to the ParseQuery which is .setSkip but I can't seem to replicate a project in java eclipse with only the wrapper code. It would go right under the .setLimit which is already in the lib.
 

DonManfred

Expert
Licensed User
Longtime User
Any chance you could provide a zipped complete eclipse project with the parse source?
As i dont have the native parse jar this gives me a lot of errors here but it should work if you reference the native jar in the Projects Build-Path-Configuration
 

Attachments

  • ParseObject.zip
    22.5 KB · Views: 253

msawada

Member
Licensed User
Longtime User
As i dont have the native parse jar this gives me a lot of errors here but it should work if you reference the native jar in the Projects Build-Path-Configuration
Thank you so much Don! I will work on this today. If I can get it working I'll upload the modified lib here.
 

msawada

Member
Licensed User
Longtime User
As i dont have the native parse jar this gives me a lot of errors here but it should work if you reference the native jar in the Projects Build-Path-Configuration
Hi again Don, I've managed to get the Parse Library working in Eclipse and compiled to a B4a library. My compilation is based on Parse-1.2.5.jar (which agraham seemed to use originally). I've attached the library below if anyone else wants to use it (unzip and place all 3 files in your additional libraries folder). Since this library is based on agrahams wrapper is 1.1 and not 1.4 as is provided in the first post, anyone who uses it will have to connect with their parse keys in the Process_Globals and not in an XML file as is done with 1.4. For example, the ParseDemo project (v. 1.4) works perfectly but you need the modification below in order to use my modified library with agrahams example project:

First, comment out the line in the manifest
B4X:
'SetApplicationAttribute(android:name,"anywheresoftware.b4a.objects.ParseObjectWrapper$ParseApplication")


B4X:
Sub Process_Globals
Dim Parse As Parse
End Sub
Sub Activity_Create(FirstTime As Boolean)

'if changing to new library v1.4 (the first one in this post by agraham) for parse then uncomment the 'SetApplicationAttribute(android:name,"anywheresoftware.b4a.objects.ParseObjectWrapper$ParseApplication") in the manifest and comment out this initialize line
   Parse.Initialize("YourAppID","YourClientKey" )

End Sub

I've wrapped two new methods into the library for parse queries:

  • Skip(v)
You can skip the first results with setSkip. This can be useful for pagination.
v as Int: an integer telling the query the record index to begin querying at.
This is useful if you want to return more than 1000 records from a parse query since you can only do so with a loop and a Skip otherwise parse will return a maximum of 1000 records only.​

  • whereWithinGeoBox(southwest,northeast)
Add a constraint to the query that requires a particular key's coordinates to be contained within a given rectangular geographic bounding box,
southwest as ParseGeoPoint: The lower-left inclusive corner of the box.
northeast as ParseGeoPoint: The upper-right inclusive corner of the box.​

They are used like the following:
B4X:
Dim query As ParseQuery
query.Initialize("MyTable")
query.Limit=queryLimit
query.Skip=2*1000 'start at record 2000
query.whereWithinGeoBox("location",pgeoSW,pgeoNE) 'pgeoSW,pgeoNE are parse geopoints
query.Find("query", 2)
ProgressDialogShow("Waiting for response.")
I'll upload the full eclipse project that I have working with the modified wrapper in case anyone else wants to change things.
 

Attachments

  • ParseLibs.zip
    450.7 KB · Views: 302
Last edited:

holdemadvantage

Active Member
Licensed User
Longtime User
Sorry for my question, but.. i have to send Alert in different languages on the basis of user's defaulta language
I notice that alert is recived in the language you send , is there a way to parse the alert string (for example en:Hallo" for an english notifiction) and display a custom message (in this case "Hello") if a user's default language is en ?

I get default language whit this sub

B4X:
Sub GetDefaultLanguage As String
Dim r As Reflector
Return r.RunStaticMethod("java.util.Locale", "getDefault", Null, Null)
End Sub

Thanks in advance
 

holdemadvantage

Active Member
Licensed User
Longtime User
I thougt it was, maybe it was not clear my concept, when totification arrive alert message is displayed as sent on parse.com but i would like to decide to write in notification bar a mssage on the basis of alert content, is it possible?
 

msawada

Member
Licensed User
Longtime User
Hi again Don, I've managed to get the Parse Library working in Eclipse and compiled to a B4a library. My compilation is based on Parse-1.2.5.jar (which agraham seemed to use originally). I've attached the library below if anyone else wants to use it (unzip and place all 3 files in your additional libraries folder). Since this library is based on agrahams wrapper is 1.1 and not 1.4 as is provided in the first post, anyone who uses it will have to connect with their parse keys in the Process_Globals and not in an XML file as is done with 1.4. For example, the ParseDemo project (v. 1.4) works perfectly but you need the modification below in order to use my modified library with agrahams example project:

Sub Process_Globals
Dim AppId, ClientKey As String
AppId = "YourAppID"
ClientKey = "YourClientKey"
Dim Parse As Parse
End Sub

I've wrapped two new methods into the library for parse queries:

  • Skip(v)
You can skip the first results with setSkip. This can be useful for pagination.
v as Int: an integer telling the query the record index to begin querying at.​

  • whereWithinGeoBox(southwest,northeast)
Add a constraint to the query that requires a particular key's coordinates to be contained within a given rectangular geographic bounding box,
southwest as ParseGeoPoint: The lower-left inclusive corner of the box.
northeast as ParseGeoPoint: The upper-right inclusive corner of the box.​

They are used like the following:

Dim query As ParseQuery
query.Initialize("MyTable")
query.Limit=queryLimit
query.Skip=2*1000 'start at record 2000
query.whereWithinGeoBox("location",pgeoSW,pgeoNE) 'pgeoSW,pgeoNE are parse geopoints
query.Find("query", 2)
ProgressDialogShow("Waiting for response.")

I'll upload the full eclipse project that I have working with the modified wrapper in case anyone else wants to change things.​

Attached is the working Eclipse Project wrapper for the lib above in the case that someone wants to use or modify it.
 

Attachments

  • ParseObject.zip
    485.2 KB · Views: 222

omidaghakhani1368

Well-Known Member
Licensed User
Longtime User
Hi.
I get error unfortunately has stopped,why?
I use this library in last and not have a problem
What solution?
 

stu14t

Active Member
Licensed User
Longtime User
I've sat down today and final started to try and access the ParseUser object with some success. Below is the code used to Login (I already have a user setup in Parse)

B4X:
Sub ParseLogin As JavaObject
    Dim PL As JavaObject
    PL.InitializeStatic("com.parse.ParseUser")
    Result = PL.RunMethodJO("logIn" , Array As Object (UserName,Password))
    Log(Result)
    Return Result
End Sub

The above code works fine but the Parse code points to a different method :

"Typically, you should use ParseUser.logInInBackground(java.lang.String, java.lang.String) instead of this, unless you are managing your own threading."

Is the the method I use at the top of the post OK or should I use this suggested method below?

B4X:
ParseUser.logInInBackground("UserName", "Password", new LogInCallback()

If so I'm struggling with how to handle the callback using the Java Object.

The other issue I'm struggling with is accessing the "Result" object. When I log in successfully the log returns the following:

B4X:
 (ParseUser) com.parse.ParseUser@1947c16f

and the "Result" object looks like this in the watch window

Capture.JPG



And I've tried to extract the data using the following code:

B4X:
UserID = Result.GetFieldJO("objectid")


And get this error:

B4X:
** Activity (main) Resume **
** Activity (main) Pause, UserClosed = false **
sending message to waiting queue (CallSubDelayed - HeartBeat)
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
(ParseUser) com.parse.ParseUser@1947c16f
Error occurred on line: 86 (main)
java.lang.RuntimeException: Field: objectid not found in: com.parse.ParseUser
    at anywheresoftware.b4j.object.JavaObject$FieldCache.getField(JavaObject.java:305)
    at anywheresoftware.b4j.object.JavaObject.GetField(JavaObject.java:180)
    at anywheresoftware.b4j.object.JavaObject.GetFieldJO(JavaObject.java:187)
    at java.lang.reflect.Method.invoke(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:372)
    at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:636)
    at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:302)
    at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:238)
    at java.lang.reflect.Method.invoke(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:372)
    at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:121)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:175)
    at anywheresoftware.b4a.BA.raiseEvent(BA.java:171)
    at anywheresoftware.b4a.objects.ViewWrapper$1.onClick(ViewWrapper.java:77)
    at android.view.View.performClick(View.java:4764)
    at android.view.View$PerformClick.run(View.java:19844)
    at android.os.Handler.handleCallback(Handler.java:739)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:135)
    at android.app.ActivityThread.main(ActivityThread.java:5349)
    at java.lang.reflect.Method.invoke(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:372)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:908)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:703)
running waiting messages (1)
** Activity (main) Resume **

This is probably a daft question but how come I can see objectid in the watch window but can't extract it from the object?
 
Last edited:

Dave61

Member
Licensed User
Longtime User
I am getting the same error as reported here a lot: "Unfortunately, ParseDemo has stopped.".
I am using B4A 5.02 and Parse SDK 1.9.2 and the Parse library 1.4.

I guess unless I recompile (which I have no idea how to do) or use an older version than 1.7 of the Parse SDK (which I haven't located), this connection to Parse is not going to work?
 
Top