Android Question Back4app Parse server authentication

Alvsky

Member
Licensed User
Longtime User
Hi
I decided to use Back4app Parse server for my project as a backend.

I wonder did someone try to communicate with parse server and how?
Since the only Parse library I found here is outdated, and I am not very skilled programmer :), I decided that CURL is the best (i.e. easiest ;) ) way to connect with back4app server (using API and REST keys).

So far, I managed to implement all CRUD operations on parse objects.
the "only" thing I have problems with is the authentication.
I can make Register and Login with no problems.

Here are my questions:

When I sign in (or register) a session token is created on back4app server.
What exactly I do with it? Do I have to store it in a variable and check it every time I do some CRUD operations, or something else.

How do I Logout?
I couldn't find it in documentation (https://dashboard.back4app.com/apidocs#User-custom-class)

... and in the parseproject.org documentation it is explained, but I can not get it to work
(https://docs.parseplatform.org/rest/guide/#deleting-sessions)

I hope someone did this and can help me.

A.
 

DonManfred

Expert
Licensed User
Longtime User
The Location header will contain the endpoint of the newly-created object.

So you probably get it in the headers of the job request-result.

What is the code you are using and what exactly is the error message you got?
 
Upvote 0

Alvsky

Member
Licensed User
Longtime User
Hi
thanks for the tip...
I did a little bit of digging (or a lot :)) and managed to implement a registration/login/logout process (for now)

I did in in a way that I have a DB table with parseUser, parseObjectID and session_token columns alongside all others usual columns needed for a user.

My app tracks crop harvest on the farm and main user is actually a company so I have one predefined company in my DB in table 'company'.

When new company (user) registers I update parseUser, parseObjectID and session_token with actual data.
On logout, I delete 'session_token' (i.e. I update it with blank string ("") )

When application starts first the check is done if parseUser field is empty or not. If it is empty Register activity is shown.

for login, the check is done if session_token is empty or not and according to result SingIn activity is shown or not.

Here is the code:

B4X:
'MAIN activity
Sub Process_Globals
    
    Dim AppID = "xxxxxxxx" As String
    Dim RESTid = "xxxxxxxx" As String
    Dim parseServerLink = "https://parseapi.back4app.com/" As String

    
'...

End Sub

'...

Sub checkCompanyIdInternal 
   Log("checkCompanyIdInternal")
   dbC = SQL1.ExecQuery("SELECT * FROM 'company' WHERE id = '1'")
   dbC.Position=0

   If dbC.GetString("parse_objectID") <> "" Then
       company_id = dbC.GetString("id")
       company_name = dbC.GetString("name")
       parse_objectID = dbC.GetString("parse_objectID")
       sessionToken = dbC.GetString("session_token")
       If sessionToken = "" Then
           lblCompanyName.Text = company_name&" (Odjavljeni ste)"
           Else
           lblCompanyName.Text = company_name
       End If
     
       Else
           Log("idi na Register")
           StartActivity(actRegister)
           Activity.Finish
           
   End If
   
   dbC.Close
End Sub

Sub logout

       Dim curl As HttpJob
       curl.Initialize("", Me)
       curl.PostString(parseServerLink&"logout","")
   
       curl.GetRequest.SetHeader("X-Parse-Application-Id",AppID)
       curl.GetRequest.SetHeader("X-Parse-REST-API-Key",RESTid)
       curl.GetRequest.SetHeader("X-Parse-Session-Token",sessionToken)
       SQL1.ExecNonQuery2("UPDATE company SET session_token=? WHERE id= ?",Array As String("", 1))
       curl.Release
       Activity.Finish
       ExitApplication

End Sub


'REGISTER activity

Sub btnswRegister_Click
   kbrd.HideKeyboard
   
   Dim j As HttpJob
   j.Initialize("log-in", Me)
   Dim user As Map
   user.Initialize
   user.Put("username", fldRegEmail.Text)
   user.Put("password", fldRegPassword.Text)
   user.Put("email", fldRegEmail.Text)
   user.Put("company_name", fldRegCompany.Text)
   user.Put("name", fldRegName.Text)
   user.Put("last_name", fldRegLastName.Text)
   user.Put("oib", fldRegOIB.Text)
   Dim gen As JSONGenerator
   gen.Initialize(user)
   j.PostString(Main.parseServerLink&"users", gen.ToString)
   j.GetRequest.SetHeader("X-Parse-Application-Id", Main.AppID)
   j.GetRequest.SetHeader("X-Parse-REST-API-Key", Main.RESTid)
   j.GetRequest.SetHeader("X-Parse-Revocable-Session", "1")
   j.GetRequest.SetContentType("application/json")
   
   j.Release

End Sub

Sub JobDone(job As HttpJob)
   If job.Success Then
       Log(job.GetString)
       
       Dim parser As JSONParser
       parser.Initialize(job.GetString)
       Dim root As Map = parser.NextObject
       Dim objectId As String = root.Get("objectId")
       Dim sessionToken As String = root.Get("sessionToken")
          
   If fldRegOIB.Text = "" Then fldRegOIB.Text = "0"
   
       Main.SQL1.ExecNonQuery2("UPDATE company SET parse_objectID=?, session_token=?, name=?, oib=?, email=?, username=?",Array As String(objectId, sessionToken, fldRegCompany.Text, fldRegOIB.Text, fldRegEmail.Text, fldRegEmail.Text))

       StartActivity(Main)
       Activity.Finish

   Else
       Log(job.ErrorMessage)
       lblError.Text = job.ErrorMessage
       dialogAlert.ShowCustom(pnlErr, "OK", "", "")
           
   End If
   job.Release
End Sub


'SIGN IN activity

Sub btnswSignIn_Click
   Dim j As HttpJob
   j.Initialize("log-in", Me)
   j.Download(Main.parseServerLink&"login?username="&fldRegEmail.Text&"&password="&fldRegPassword.Text&"")
   j.GetRequest.SetHeader("accept","application/json")
   j.GetRequest.SetHeader("X-Parse-Application-Id", Main.AppID)
   j.GetRequest.SetHeader("X-Parse-REST-API-Key", Main.RESTid)
   j.GetRequest.SetHeader("X-Parse-Revocable-Session", "1")
   
End Sub

Sub JobDone(job As HttpJob)
   If job.Success Then
       Log(job.GetString)
       
       Dim parser As JSONParser
       parser.Initialize(job.GetString)
       Dim root As Map = parser.NextObject
       Dim objectId As String = root.Get("objectId")
       Dim sessionToken As String = root.Get("sessionToken")
       Log(objectId &" -- "&sessionToken)
   
       Main.SQL1.ExecNonQuery2("UPDATE company SET session_token=? WHERE id= ?",Array As String(sessionToken, 1))


       StartActivity(Main)
       Activity.Finish

   Else
       Log(job.ErrorMessage)
           
   End If
   job.Release
End Sub


I hope this will help someone. At least to start with something.

And of course, if I did something wrong and someone notices I would appreciate a correction :)
 
Upvote 0
It is a good example of using cUrl command on back4app by httpJob!

https://dashboard.back4app.com/apidocs?shell#reading-objects provided:
curl:
curl -X GET \
-H "X-Parse-Application-Id: BCrUQVkk80pCdeImSXoKXL5ZCtyyEZwbN7mAb11f" \
-H "X-Parse-REST-API-Key: swrFFIXJlFudtF3HkZPtfybDFRTmS7sPwvGUzQ9w" \
-G \
--data-urlencode "where={\"myCustomKey1Name\":\"myCustomKey1Value\"}" \
https://parseapi.back4app.com/classes/MyCustomClassName

https://dashboard.back4app.com/apidocs?shell#creating-objects provided:
curl:
curl -X POST \
-H "X-Parse-Application-Id: BCrUQVkk80pCdeImSXoKXL5ZCtyyEZwbN7mAb11f" \
-H "X-Parse-REST-API-Key: swrFFIXJlFudtF3HkZPtfybDFRTmS7sPwvGUzQ9w" \
-H "Content-Type: application/json" \
-d '{"myCustomKey1Name":"myCustomKey1Value","myCustomKey2Name":"myCustomKey2Value"}' \
https://parseapi.back4app.com/classes/MyCustomClassName

I translate these curl commands into B4A codes:
b4a:
Sub sendBack4AppRequest()
    Dim Job As HttpJob
    Job.initialize("request", Me)
    Job.Download($"https://parseapi.back4app.com/classes/B4aVehicle?where={"price": {"${Chr(36)}gt":5000} }"$)
    Job.GetRequest.SetHeader("X-Parse-Application-Id", "BCrUQVkk80pCdeImSXoKXL5ZCtyyEZwbN7mAb11f")
    Job.GetRequest.SetHeader("X-Parse-REST-API-Key", "swrFFIXJlFudtF3HkZPtfybDFRTmS7sPwvGUzQ9w")
End Sub

Sub postdataBack4App(i_name As String, i_prc As Int, i_color As String)       
    If i_name = "" Then i_name = "Window"
    If i_prc = 0 Then i_prc = 10000
    If i_color = "" Then i_color = "Blue"   
    'strdata = $"{"name":"${i_name}","price":${i_prc},"color":"${i_color}"}"$
    Dim strdata As String = map2JsonStr(CreateMap("name": i_name, "price": i_prc, "color": i_color))
    Log("strdata: " & strdata)
    Dim Job As HttpJob
    Job.initialize("post", Me)
    Job.PostString("https://parseapi.back4app.com/classes/B4aVehicle", strdata)
    Job.GetRequest.SetHeader("X-Parse-Application-Id", "BCrUQVkk80pCdeImSXoKXL5ZCtyyEZwbN7mAb11f")
    Job.GetRequest.SetHeader("X-Parse-REST-API-Key", "swrFFIXJlFudtF3HkZPtfybDFRTmS7sPwvGUzQ9w")
    Job.GetRequest.SetContentType("application/json")
    ProgressDialogShow("Saving...")
End Sub

Sub JobDone(j As HttpJob)
    If j.Success Then
        Log(j.GetString)
        If j.JobName = "request" Then
            Try
                Dim jparser As JSONParser
                jparser.Initialize(j.GetString)           
                Dim map1 As Map = jparser.Nextobject
                Dim lst1 As List = map1.Get("results")
                ListView1.Clear
                fillTheList(lst1)
            Catch
                Log(LastException)
            End Try
        End If
        If j.JobName = "post" Then
            Try
                Dim jparser As JSONParser
                jparser.Initialize(j.GetString)
                Dim map2 As Map = jparser.NextObject
                Msgbox2Async($"objectId: ${map2.Get("objectId")}${CRLF}createdAt: ${map2.Get("createdAt")}"$, "Response","Done","","",Null, True)
                sendBack4AppRequest
            Catch
                Log(LastException)
            End Try
        End If
    End If
    j.Release
End Sub
 
Upvote 0
Hi Erel,

In this case, the JobDone sub is common event handler for both sendBack4AppRequest and postdataBack4App.
i.e. centralize the responses in one point for me easier to debug :p

By using Wait For JobDone, the codes above were edited as:
b4a:
Sub sendBack4AppRequest()
    Dim Job As HttpJob
    Job.initialize("query", Me)
    'Job.Download($"https://parseapi.back4app.com/classes/B4aVehicle?where={"price": 5000 }"$)
    Job.Download($"https://parseapi.back4app.com/classes/B4aVehicle?where={"price": {"${Chr(36)}gt":5000} }"$)
    Job.GetRequest.SetHeader("X-Parse-Application-Id", appid)
    Job.GetRequest.SetHeader("X-Parse-REST-API-Key", apikey)
    Wait For JobDone(j As HttpJob)
    If j.Success Then
        Log(j.GetString)       
        Try
            Dim jparser As JSONParser
            jparser.Initialize(j.GetString)
            Dim map1 As Map = jparser.Nextobject
            Dim lst1 As List = map1.Get("results")
            ListView1.Clear
            fillTheList(lst1)
        Catch
            Log(LastException)
        End Try       
    End If
    j.Release
End Sub

b4a:
Sub postdataBack4App(i_name As String, i_prc As Int, i_color As String)       
    If i_name = "" Then i_name = "Window"
    If i_prc = 0 Then i_prc = 10000
    If i_color = "" Then i_color = "Blue"   
    'strdata = $"{"name":"${i_name}","price":${i_prc},"color":"${i_color}"}"$
    Dim strdata As String = map2JsonStr(CreateMap("name": i_name, "price": i_prc, "color": i_color))
    Log("strdata: " & strdata)
    Dim Job As HttpJob
    Job.initialize("post", Me)
    Job.PostString("https://parseapi.back4app.com/classes/B4aVehicle", strdata)
    Job.GetRequest.SetHeader("X-Parse-Application-Id", appid)
    Job.GetRequest.SetHeader("X-Parse-REST-API-Key", apikey)
    Job.GetRequest.SetContentType("application/json")
    ProgressDialogShow("Saving...")
    Wait For JobDone(j As HttpJob)
    ProgressDialogHide
    If j.Success Then
        Log(j.GetString)       
        Try
            Dim jparser As JSONParser
            jparser.Initialize(j.GetString)
            Dim map2 As Map = jparser.NextObject
            Msgbox2Async($"objectId: ${map2.Get("objectId")}${CRLF}createdAt: ${map2.Get("createdAt")}"$, "Response","Done","","",Null, True)
            sendBack4AppRequest
        Catch
            Log(LastException)
        End Try
    End If   
    j.Release
End Sub
 
Upvote 0
When using C#, the code is changed as:

implement cURL by C#:
private void postdataBack4App()
{
    // using TLS 1.2
    System.Net.ServicePointManager.SecurityProtocol = (System.Net.SecurityProtocolType)3072;
    string myurl = "https://parseapi.back4app.com/classes/B4aVehicle";
    string sendData = "{\"name\":\"Wheel\",\"price\":1000,\"color\":\"black\"}";
    System.Net.WebClient web = new System.Net.WebClient();
    web.Headers.Add(System.Net.HttpRequestHeader.Accept, "application/json");
    web.Headers.Add(System.Net.HttpRequestHeader.ContentType, "application/json");
    web.Headers.Add("X-Parse-Application-Id", your_app_id);
    web.Headers.Add("X-Parse-REST-API-Key", your_rest_api_key);
    try
    {
        var response = web.UploadString(myurl, "POST", sendData);
        var jsonResultToDict = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, string>>(response);
    }
    catch (Exception ex)
    {
        MessageBox.Show("Post Error: " + Environment.NewLine + ex.Message);
    }
}
 
Upvote 0
Dear Erel,
I change it doing asynchronously as:

async:
private async Task postdataBack4App()
{
    // using TLS 1.2
    System.Net.ServicePointManager.SecurityProtocol = (System.Net.SecurityProtocolType)3072;
    string myurl = "https://parseapi.back4app.com/classes/B4aVehicle";
    string sendData = "{\"name\":\"Wheel\",\"price\":1000,\"color\":\"black\"}";
    System.Net.WebClient web = new System.Net.WebClient();
    web.Headers.Add(System.Net.HttpRequestHeader.Accept, "application/json");
    web.Headers.Add(System.Net.HttpRequestHeader.ContentType, "application/json");
    web.Headers.Add("X-Parse-Application-Id", your_app_id);
    web.Headers.Add("X-Parse-REST-API-Key", your_rest_api_key);
    try
    {
        //var response = web.UploadString(myurl, "POST", sendData);
        string response = await web.UploadStringTaskAsync(myurl, sendData);
        var jsonResultToDict = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, string>>(response);
    }
    catch (Exception ex)
    {
        MessageBox.Show("Post Error: " + Environment.NewLine + ex.Message);
    }
}
call this function:
Await(Task.WhenAll(postdataBack4App()));
 
Upvote 0
Top