App That Uses Maps API

Hey Rob,

Installed my app on another android phone today and everything was working fine on it, except for the getUserLocation function which I know I can easily fix, but thanks for the help! I’ll be posting again if I get stuck with something else.

Hey Rob,

Its been a while, been taking breaks on my project because college. Just had a question regarding storing location in a myql database. I don’t know if you’ve done any of this before in one of your projects or simply messing around, but, I’m not entirely sure what the best way of storing location in a database is, taking into consideration I would like to do some simple(?) arithmetic on locations to determine distance from x location to y location. From what I read online, some people recommended using spatial point datatype in mysql, but some people think it’s kind of limiting. Other people suggested storing lat and long as a floating point (10,6). For now, i’m using the latter.

Do you have any advice?

Thanks in advance,

YL

I’d store the lat and long as floats. If you need the spatial data type (I didn’t know there was one), then use it too. It won’t hurt to have both and you may find at times you need lat, long for somethings and the other datapoint for others.

Rob

Hey Rob,

I took a break from my project, but now I’m back on track. I am currently working on a feature of my app that gets the current location of the user and does a network request to run a php script that finds other people in the database that are in a 25 mile radius of the sent location. I haven’t worked with php in a bit, but i was able to get the script to successfully find nearby users, but only through an html form, not the app. I haven’t tried to use the script with the app yet because I know (or at least i think i know) that using:

while ($row = mysqli\_fetch\_assoc($result))

to loop through the results of the query (as I doing am now) wont return the right information to the app, only the last row of the query, I believe. Any tips on how i could return a table/array of the resullts of the query to the app as the network response? Probably with a JSON table or something like that?

Thank you in advance!

How are you doing your query?

I would also setup another array perhaps something like:

$items = array(); $i  = 0; while( $row = mysqli\_fetch\_assoc($result) ) {     $items[$i++] = $row; end echo( json\_encode( $items ) );

(untested code)

Rob

 Like this:

$query = "SELECT id, ( 3959 \* acos( cos( radians('".$currentLat."') ) \* cos( radians( '".$currentLng."' ) ) \* cos( radians( lng ) - radians('".$currentLng."') ) + sin( radians('".$currentLat."') ) \* sin( radians( lat ) ) ) ) AS distance FROM USER HAVING distance \< 25 ORDER BY distance LIMIT 0 , 20"; $result = mysqli\_query($conn, $query);

Looks like it will work. Trying it out right now.

Hey Rob,

Got my php script working as intended, tested it with an html form and everything seems to work how i want it to. Unfortunately though, i cant seem to get it to work with my app. I’ve been going through my code but i cant find the problem.

heres the relevant parts of my code:

local function networkListener( event ) if ( event.isError ) then print( "Network error: ", event.response ) alert = native.showAlert( "No GPS Signal", "Can't sync with GPS.", { "Okay" } ) else print ( "Upload complete!" ) myTable = json.decode(event.response) addressBar.text = myTable.barberid .. myTable.barberid .. myTable menu.title.text = myTable[1].barberid .. myTable.barberid .. myTable --these are all just for testing to see if im getting the right info back from the network response --alert = native.showAlert("test", myTable[1].barberid, { "Okay" } ) --alert = native.showAlert("test", myTable.barberid, { "Okay" } ) end local params = {} local body = {} params.headers = headers --handler for a test button4 local function testEvent(event) local phase = event.phase if phase == "ended" then --currentLocation is defined earlier from the map:getUserLocation params.body = "currentLat=" .. currentLocation.latitude .. "&currentLng=" .. currentLocation.longitude network.request( "http://107.170.34.199/barber\_search\_script.php", "POST", networkListener, params) return true end end end

any help would be appreciated!

First, are you using $_POST and not $_GET? PHP has some weirdness with $_POST requests at times. You can put come echo statements or print_r()'s in your PHP script to make sure $_POST[] is actually being populated.

HTTP requests are known as VERBS:  GET, POST, PUT, DELETE, and a few others. There are two concepts when deciding to use POST vs GET. First is data size. GET is limited to around 200 characters or so in the URL after the ?. POST has a much larger limit. Since you’re only sending a couple of numbers, GET is a much easier way to deal with this. The next is semantics. The verbs are named the way they are for a reason. If you think of database options: CREATE, READ, UPDATE, DELETE (CRUD). These kind of map to POST, GET, PUT, DELETE. That is GET is for getting data fro the server. POST is for sending data to the server. Some people use PUT for updating.

Semantically speaking you are GETting a list of location matches cased on a couple of parameters.

Also switching to get means not dealing with the params table which will simplify  your code.

local function networkListener( event ) if ( event.isError ) then print( "Network error: ", event.response ) alert = native.showAlert( "No GPS Signal", "Can't sync with GPS.", { "Okay" } ) -- this is not true. .isError will be true if the server timed out or could not be reached. -- It has nothing to do with the GPS. else print ( "Upload complete!" ) -- you're not really uploading anything myTable = json.decode(event.response) addressBar.text = myTable.barberid .. myTable.barberid .. myTable menu.title.text = myTable[1].barberid .. myTable.barberid .. myTable --these are all just for testing to see if im getting the right info back from the network response --alert = native.showAlert("test", myTable[1].barberid, { "Okay" } ) --alert = native.showAlert("test", myTable.barberid, { "Okay" } ) end end local params = {} params.headers = headers -- what are your headers? --handler for a test button4 local function testEvent(event) local phase = event.phase if phase == "ended" then --currentLocation is defined earlier from the map:getUserLocation local URL = "http://107.170.34.199/barber\_search\_script.php?" .. "currentLat=" .. currentLocation.latitude .. "&currentLng=" .. currentLocation.longitude network.request( URL, "GET", networkListener, params) return true end return false end

I added some comments in line. Change your PHP script to use $_GET[]; and I think you will be in business. If not, and you get .isError you need to print out event.response and event.status to get a clue as to why it failed. If .isError is false, and you’re not getting what you expect you should print out event.response and see what your script is really sending back.

Ill update it to use GET and see if it works, i might have to change it back to POST after though because originally i meant to also insert the users current location into the database, just had it not do that for now.

And just to clarify and not make myself look so silly, a lot of the code was just copy and pasted from another file im using in my app that also uses network request (account registration one), thats why a lot of the stuff there shouldn’t be there, I was just being lazy and didnt feel like changing a lot of it because in the end i meant to remove all that anyways, it was just to test to see if i was getting any network response at all. Some of the alerts were also just copied and pasted from other chunks of code on the same file just to show an alert to see whether there was an network error or not, not meant to actually work that way in the end (hence the alert no GPS signal and stuff, this is my mapScene.lua).

Also, i used alerts and changing addressBar.text because maps dont work in the simulator, so im not able to see the errors or any of that.

Do i need to have params.headers if i dont have any specific headers? To be completely honest with you i never really learned what the headers were for, i simply used some of the code of from the docs of the network.request and worked off of that (it had the params.headers in there)

Thanks Rob!

All right so i updated my php script to use GET, changed my html form to use GET too, and it works like it did before.

I changed my lua code as well to use GET instead of POST, i just tested it again on my device and i get the same results. The weird part is when i press the test button, nothing happens, neither conditions of the network listener are being met (apparently), because im not getting any alerts or having the text of the address bar changed either, so I dont understand where the problem is. I think maybe the network.request isn’t even going through at all? What do you think?

Until you post some log messages from the device and check your server logs looking for PHP errors, I can’t really advise much more on this. Verify the script works in a web browser by typing in the URL as you have it in your network.request().

Rob

Got adb setup finally, i can’t believe ive been working on this app for this long without having adb installed… Anyhow, i think i found the problem. The php script is actually working with the app, but im having a hard time using the data sent back as a JSON table.

I tried changing the JSON table a bit, but none of them worked as i expected.

$barbers = array(); $q = 1; #$barbers = array('barber'.$q =\> $row); $barbers['barber'.$q] = $row; $q++;

then on the app i tried (among other variations which i deleted):

print(myTable.barber1[barberid]) print(myTable.barber1)

The one time i got nil on the console, and every other time i dont get anything printed out.

What would the right way to print out values from the json table be? On the php script i tested using a 2d array like this:

echo $barbers[barber1][barberid];

and it printed out the right value, i just dont know how it would be on the client side once the table is json encoded and decoded.

Why not just do:

$barbers = array();

$q = 1;

$barbers[$q] = $row;

$q++;

You end up with:

myTable[1].barberid

myTable[2].barberid

It would really help to see a print out of what event.response is. But I think you can simplify your life quite a bit by not over complicating your data.

Thats what i did originally and i was getting nothing back from the network request! I just changed it back to that, i was doing the client side wrong, something like myTable.barberid[1], getting no results obviously, so i started changing up things to see if i could get it to work.

I now changed it to:

myTable[1].barberid

And the console is printing (from event.response):

[]

and printing nothing from:

print (myTable[1].barberid)

I also tested using the script with an html form to see if it actually found anything in the database using the same lat and lng values the app would send, and it did return more than 1 row from the query

Can you post your PHP script?

\<?php require 'connection.php'; if (!$conn) {die( "Connection failed: " . mysqli\_connect\_error());} $currentLat = mysqli\_real\_escape\_string($conn, $\_GET['currentLat']); $currentLng = mysqli\_real\_escape\_string($conn, $\_GET['currentLng']); #probably very unnecessary to escape these, just left it for good measure. $query = "SELECT barberid, ( 3959 \* acos( cos( radians('".$currentLat."') ) \* cos( radians( lat ) ) \* cos( radians( lng ) - radians('".$currentLng."') ) + sin( radians('".$currentLat."') ) \* sin( radians( lat ) ) ) ) AS distance FROM BARBER HAVING distance \< 25 ORDER BY distance LIMIT 0 , 20"; $result = mysqli\_query($conn, $query); $barbers = array(); $q = 1; if (mysqli\_num\_rows($result) \> 0) { while ($row = mysqli\_fetch\_assoc($result)){ $barbers[$q] = $row; $q++; } } echo json\_encode($barbers); mysqli\_stmt\_close($query); mysqli\_close($conn); ?\>

And just in case, this is what the script prints when run from an html form given the same lat and lng values the app would send:

{“1”:{“barberid”:“2”,“distance”:“0.049465115746106174”},“2”:{“barberid”:“5”,“distance”:“0.049465115746106174”},“3”:{“barberid”:“6”,“distance”:“0.049465115746106174”}}

Put this line at the top of your network request listener function:

print( json.prettify( event ) )

And then copy/paste the output from your adb logcat for it and post it here please.

Rob

I/Corona  ( 9276): {
I/Corona  ( 9276):   “bytesEstimated”:2,
I/Corona  ( 9276):   “bytesTransferred”:2,
I/Corona  ( 9276):   “name”:“networkRequest”,
I/Corona  ( 9276):   “phase”:“ended”,
I/Corona  ( 9276):   “requestId”:"<type ‘userdata’ is not supported by JSON.>",
I/Corona  ( 9276):   “response”:"[]",
I/Corona  ( 9276):   “responseHeaders”:{
I/Corona  ( 9276):     “Connection”:“Keep-Alive”,
I/Corona  ( 9276):     “Content-Length”:“2”,
I/Corona  ( 9276):     “X-Android-Response-Source”:“NETWORK 200”,
I/Corona  ( 9276):     “Date”:“Sun, 17 Jul 2016 22:26:23 GMT”,
I/Corona  ( 9276):     “X-Android-Sent-Millis”:“1468794376204”,
I/Corona  ( 9276):     “X-Android-Received-Millis”:“1468794376261”,
I/Corona  ( 9276):     “X-Android-Selected-Transport”:“http/1.1”,
I/Corona  ( 9276):     “Keep-Alive”:“timeout=5, max=100”,
I/Corona  ( 9276):     “X-Powered-By”:“PHP/5.5.9-1ubuntu4.14”,
I/Corona  ( 9276):     “Content-Type”:“text/html”,
I/Corona  ( 9276):     “HTTP-STATUS-LINE”:“HTTP/1.1 200 OK”,
I/Corona  ( 9276):     “Server”:“Apache/2.4.7 (Ubuntu)”
I/Corona  ( 9276):   },
I/Corona  ( 9276):   “responseType”:“text”,
I/Corona  ( 9276):   “status”:200,
I/Corona  ( 9276):   “url”:"http://107.170.34.199/barber_search_script.php",
I/Corona  ( 9276):   “isError”:false
I/Corona  ( 9276): }
I/Corona  ( 9276): Upload complete!
I/Corona  ( 9276): []

Can you print the value of the URL you’re calling? I just tried to hand build the URL using my local latitude and longitude and I got [] back.  It’s possible you’re URL you’re actually using in your app is not returning any values from the script.

Did you mean to just do print(URL)? which was:

URL = “http://107.170.34.199/barber_search_script.php?” … “currentLat=” … currentLocation.latitude … “&currentLng=” … currentLocation.longitude

it prints:

nil