Ad

Google Places Nearby API Success 200, But Returns "INVALID_REQUEST" In Laravel

I'm trying to make an iterative crawler for the Google Places API. As anyone who has used their API knows, the response only contains 20 results per page and I'm attempting to get the full list of results so I've created an loop which will execute a function if the next_page_token field is present. The most peculiar thing happens because it successfully retrieves and echos the first 20 results but fails to perform the second search, but doesn't throw any errors in Laravel. The code for this looks as follows (this is in Laravel)

public function getAllPlaces(){
        if (Auth::user()->id != '5') {
            return redirect('/userlanding')->with('error', 'Denied access');
        } else {
            $client = new Client();

            $types = 'park';

            $radius = '50000';

            $location = [

                'latitude' => '36.187740',

                'longitude' => '-92.731422'

            ];

            $keyword = '';

            $requestQuery = "https://maps.googleapis.com/maps/api/place/nearbysearch/json?location={$location['latitude']},{$location['longitude']}&radius={$radius}&type={$types}{$keyword}&key=MYSUPERSECRETKEY";

            $response = $client->request('GET', $requestQuery);
            $statusCode = $response->getStatusCode();
            $body = $response->getBody()->getContents();

            $body = json_decode($body);

            $numofrecordspresent = 0;

            $data = $body->results;

            $results = collect();
            foreach($data as $result) {
                 $results->push($result;      
                 $numofrecordspresent = $numofrecordspresent + 1;
                }
            }

            if(isset($body->next_page_token)) {
                $loopData = [

                    'nexttoken' => $body->next_page_token,

                    'locationData' => $location,

                    'numofrecordspresent' => $numofrecordspresent,

                    'radius' => $radius,

                    'types' => $types,

                    'keyword' => $keyword,

                    'client' => $client,

                ];

                $this->loopedPlaceSearch($loopData);
            } else {
                return view('apireturnpage')->with('numofrecordspresent', $numofrecordspresent);
            }
        }
    }

    public function loopedPlaceSearch($loopData) {
        $client = new Client();

        $location = $loopData['locationData'];
        $numofrecordspresent = $loopData['numofrecordspresent'];
        $pagetoken = $loopData['nexttoken'];
        $radius = $loopData['radius'];
        $types = $loopData['types'];
        $keyword = $loopData['keyword'];

        $requestQuery = "https://maps.googleapis.com/maps/api/place/nearbysearch/json?location={$location['latitude']},{$location['longitude']}&radius={$radius}&type={$types}{$keyword}&pagetoken={$pagetoken}&key=MYSUPERSECRETKEY";

        $response = $client->request('GET', $requestQuery);
        $statusCode = $response->getStatusCode();
        $body = $response->getBody()->getContents();

        $body = json_decode($body);

        $data = $body->results;

        $results = collect();
        foreach($data as $result) {
             $results->push($result;      
             $numofrecordspresent = $numofrecordspresent + 1;
            }
        }

        if (isset($body->next_page_token)) {
            $loopData = [

                'nexttoken' => $body->next_page_token,

                'locationData' => $location,

                'numofrecordspresent' => $numofrecordspresent,

            ];


            $this->loopedPlaceSearch($loopData);
        } else {
            return view('apireturnpage')->with('numofrecordspresent', $numofrecordspresent);
        }
    }

At the moment, to elaborate on what I said earlier, the first function which is the one called from web.php works just fine, pushing all 20 results onto the results collection, but when there is more results (i.e. the next_page_token is present), the second function gets called but returns "INVALID_REQUEST" in the body. This is extremely weird because taking the exact actual query string from the second function that gets used but fails and putting it into my URL bar returns the proper response, ruling out any typos in the API call.

Any help would be greatly appreciated, seems to be a bug and I can't figure out why it isn't working.

Ad

Answer

It's been a while since I made this post, but for those just finding this now with the same issue, I figured I'd explain why this happened and how I fixed it. Turns out, without a delay in the script, the server attempts to make another request while the other response is still being returned, which causes the issue in question. This is fixed very simply by adding a sleep() or usleep() before making each request, in order to prevent multiple calls at the same time.

EDIT (5/10/20): This solution is still valid, but the reasoning is not the same as I explained. The real reason why using a usleep() or sleep() function fixes this issue is because Google implemented a bottleneck on their API endpoints to prevent misuse. It only allows one request per 1-3 seconds depending on the API and anymore will cause this error to occur. I only know this because I reached out to Google directly and that was the response I received from a technical support employee at Google.

Ad
source: stackoverflow.com
Ad