0

I'm using a restricted Google API for my Flutter App with both package SHA1 restrictions and API restrictions. Some services only work when the package restriction is removed.

Here are the APIs currently active:

  • Directions
  • API Geocoding
  • API Geolocation
  • API Identity
  • Toolkit API
  • Maps SDK for Android
  • Maps Static API
  • Places API

Here are the services that I use in my app

  • Maps with google_maps_flutter: Works every time
  • Autocomplete with flutter_google_places: Works only when removed the restriction
  • User position with geolocator: Works every time
  • Place reviews with google_place: Works only when removed the restriction
  • Direction between two latlng with flutter_polyline_points: Works only when removed the restriction
1
  • I tried setting up Headers with package name and sha1 but nothing changed. Even tried to upgrade google_api_headers but got the same problem Commented Mar 1, 2023 at 22:03

1 Answer 1

1

Apparently, the only way to make it works is to use the official SDK. Indeed, google_maps_flutter, and geolocator work because they use Google Maps SDK instead of using custom headers as the other libraries.

One possible solution is to make the call to google maps API on the server instead of the client.

Here are three endpoints that I created to achieve this:

Autocomplete:

var axios = require('axios');
const { defineSecret } = require('firebase-functions/params');
const GOOGLE_API_KEY = defineSecret("GOOGLE_API_KEY");

exports.get_autocomplete_predictions = async (data, context) => {

    const query = data["query"];
    const language = data["language"];
    const location = data["location"];
    const country = data["country"];

    const apiKey = GOOGLE_API_KEY.value();

    const autocompleteUrl = "https://maps.googleapis.com/maps/api/place/autocomplete/json";

    const params = {
        key: apiKey,
        input: query,
        language: language,
        radius: 500,
        location: location,
        components: `country:${country}`
    };

    return axios.get(autocompleteUrl, { params })
        .then((response) => {
            return response.data["predictions"];
        })
        .catch((error) => {
            console.log(error);
        });
};

Place review (could be useful to integrate a cache system):

var axios = require('axios');
const { defineSecret } = require('firebase-functions/params');
const GOOGLE_API_KEY = defineSecret("GOOGLE_API_KEY");

exports.get_place_reviews = async (data, context) => {

    const apiKey = GOOGLE_API_KEY.value();

    const placeId = data["placeId"];
    const language = data["language"];

    const placeUrl = "https://maps.googleapis.com/maps/api/place/details/json";

    const params = {
        key: apiKey,
        place_id: placeId,
        language: language,
        fields: ["reviews"],
    };

    return axios.get(placeUrl, { params })
        .then((response) => {
            return response.data["result"]["reviews"];
        })
        .catch((error) => {
            console.log(error);
        });

};

Distance between two latlng:

const axios = require("axios");
const codec = require("@googlemaps/polyline-codec");
const { defineSecret } = require('firebase-functions/params');
const GOOGLE_API_KEY = defineSecret("GOOGLE_API_KEY");

const getDistance = async (origin, destination) => {

    const apiKey = GOOGLE_API_KEY.value();

    const params = {
        origin,
        destination,
        mode: "driving",
        avoidHighways: false,
        avoidFerries: false,
        avoidTolls: true,
        key: apiKey,
    };

    try {
        const response = await axios.get("https://maps.googleapis.com/maps/api/directions/json", {
            params,
        });

        // Check if the response contains the expected data
        if (response.data && response.data.routes && response.data.routes.length > 0) {
            // Decode the polyline coordinates
            const polylineCoordinates = codec.decode(response.data.routes[0].overview_polyline.points);

            // Calculate the total distance
            let totalDistance = 0;
            for (let i = 0; i < polylineCoordinates.length - 1; i++) {
                totalDistance += coordinateDistance(
                    polylineCoordinates[i][0],
                    polylineCoordinates[i][1],
                    polylineCoordinates[i + 1][0],
                    polylineCoordinates[i + 1][1]
                );
            }

            return totalDistance;
        }
        return Infinity;
    } catch (error) {

        return Infinity;
    }
};
function coordinateDistance(lat1, lon1, lat2, lon2) {
    var p = 0.017453292519943295;
    var a = 0.5 -
        Math.cos((lat2 - lat1) * p) / 2 +
        Math.cos(lat1 * p) * Math.cos(lat2 * p) * (1 - Math.cos((lon2 - lon1) * p)) / 2;
    return 12742 * Math.asin(Math.sqrt(a));
}
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.