mohesu / map_location_picker

Map location picker for flutter Based on google_maps_flutter
Apache License 2.0
46 stars 68 forks source link

Flutter Web AutocompletePlace XMLHttpRequest Error #14

Open Bylinkk opened 1 year ago

Bylinkk commented 1 year ago

Hi,

After reading multiple XMLHttpRequest errors and CORS security issues, I can't work the autocomplete search on Chrome. Can we just remove this function to give the user the possibility to only use the current location button? Or can you help me to make this function work easily ? Thank you in advance for your return.

rvndsngwn commented 1 year ago

Hi @Bylinkk I will update it as soon as possible. Could you please elaborate on your problem?

rvndsngwn commented 1 year ago

Hey @Bylinkk , this is caused by CORS.

Bylinkk commented 1 year ago

Thanks for your feedback. Indeed the problem is caused by CORS. When I try to use a proxy, it doesn't work. I use the geoCodingBaseUrl parameter with this value : geoCodingBaseUrl: "https://api.allorigins.win/raw?url=https://maps.googleapis.com/maps/api/geocode/json/", I also tried this : geoCodingApiHeaders: const { "Access-Control-Allow-Origin":'*', "Access-Control-Allow-Methods": 'GET', }, concerning disabled security, it works well on my side but the user will not do it on his side !

I really don't know how to solve this problem!

rvndsngwn commented 1 year ago

It seems to be only a problem with localhost, after the deployment CORS problems are automatically fixed. You can try it once 🤔 I'm not sure.

Bylinkk commented 1 year ago

Hi,

I just did the test in production but the CORS problem is still present. You can check for yourself on the following links: Pre production web site Then click on "Menu | Commande WhatsApp" then on the profile icon of the bottom app bar then "Ajouter votre adresse de livraison".

The javascript console displays the CORS error:

/#/:1 Access to XMLHttpRequest at 'https://maps.googleapis.com/maps/api/geocode/json/geocode/json?latlng=0.0017568469044719824%2C-0.002709031105041504&key=API_KEY' from origin 'https://dev2.scan.feadys.com' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

Failed to load resource: net::ERR_FAILED

Google Maps JavaScript API has been loaded directly without a callback. This is not supported and can lead to race conditions and suboptimal performance. For supported loading patterns please see https://goo.gle/js-api-loading

Thank you for your help

jansvanda commented 1 year ago

hi @rvndsngwn I am experiencing the same issue, tried already many things like adding the headers "Access-Control-Allow-Origin": "*", "Access-Control-Allow-Methods": "GET, POST, OPTIONS", "Access-Control-Allow-Headers": "X-Requested-With, Content-Type, Origin, Accept, token"

Also tried some CORS proxies, but those are just temporary solutions.

Still getting "has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.".

Tried to make server side changes, nothing helps. I don't know what to do anymore. My app works on mobile but not on web. Sadly

rvndsngwn commented 1 year ago

https://pub.dev/packages/flutter_cors

Guys you can use this package only for local testing.

rvndsngwn commented 1 year ago

https://community.flutterflow.io/c/community-tutorials/how-to-deal-with-those-cors-issues

Bylinkk commented 1 year ago

Hi @rvndsngwn I will test this. Thank you very much for your come back

thisisprabhat commented 11 months ago

I have worked on it, the same issue was with me, so I used OpenStreetMap instead and got the desired result.

AndresPinto2203 commented 7 months ago

This problem has been presented to me in several opportunities when I try to use google apis (youtube, address, places, etc) from flutter web, the way in which I have solved it is defining functions in my services api rest that make of pass buckets to make the requests to google and to return the answers to my application, in the case of the widget PlacesAutocomplete has the property placesBaseUrl, there you define your route in the backend where you consult the services of google, in my case it is: https://my.api.server.com/utils.

But the routes that I define in my server to consume the google services were:

https://my.api.server.com/utils/place/autocomplete/json?input=address exampl

for this service I use the function:

async getPlacesByInput(input: string): Promise { try { let response = await axios.get(https://maps.googleapis.com/maps/api/place/autocomplete/json?input=${input}&key=${GOOGLE_API_KEY}); if (response.status == 200) { return response.data; } } catch (error) { console.error('error', error); return {}; } }

https://my.api.server.com/utils/place/details/json?placeid=placeIdExample

and for this service I use the function:

async getPlaceDetails(placeId: string, returnAll: Boolean): Promise { try { let response = await axios.get(https://maps.googleapis.com/maps/api/place/details/json?place_id=${placeId}&key=${GOOGLE_API_KEY}); if (returnAll) { return response.data; } if (response.status == 200) { return { placeDetails: JSON.stringify(response.data.result), stateName: response.data.result.address_components.find((component: any) => component.types.includes('administrative_area_level_1'))?.long_name, }; } else { console.error(response.data); return ''; } } catch (error) { console.error('error', error); return ''; }

}

I hope my explanation helps you. Happy code!!!!

AnandSaran commented 3 months ago

How to fix this CORS issue, Any update ?

zahidshaikh08 commented 2 weeks ago

Any updates on this?? As for me it works fine on any pc's web browser but does not work from any mobile browser.

bertrandgelinas commented 2 days ago

You need to build a proxy on your server in order to be able to get your correct response. The actual service is always returning CORS issues so building your own make you control the access control.

On Flutter

GoogleMapLocationPicker(
              mapType: MapType.normal,
              geoCodingBaseUrl:
                  "Your REST (GET) API", // You need to add your API HERE
              geoCodingApiHeaders: {
                'Content-Type': 'application/json',
                'Accept': 'application/json',
              },
              searchHintText: tr(LocaleKeys.choose_location),
              apiKey: firebase.app.options.apiKey,
              currentLatLng:
                  LatLng(currentPosition.latitude, currentPosition.longitude),
              onPlacesDetailsResponse: (pick) => onPlacePicked(pick!.result),
              onNext: (pick) => onPlacePicked(pick!),
              language: "fr",
              region: "ca",
            )

I built that quick NodeJS firebase function that mimic the same URL of geocoding (in that case) :

recalculateApi.get("/geocode/json?", async (req, res) => {  // Here make sure you use the exact "/geocode/json?" to make sure it fits the actual flutter call
  const latlng = req.query.latlng as string;
  const language = req.query.language as string;
  const key = req.query.key as string;

  if (!latlng || !language || !key) {
    res.status(400).send('Missing required query parameters: latlng, language, key');
    return;
  }

  try {
    const url = `https://maps.googleapis.com/maps/api/geocode/json?latlng=${latlng}&language=${language}&key=${key}`;
    console.log(`Calling ${url}`);
    const apiResponse = await axios.get(url);

    res.status(200).send(apiResponse.data);
  } catch (error: any) {
    res.status(500).send(`Error calling Google Maps API: ${error.message}`);
  }
});

Then it works fine. That still a lot of work for something that could already work....

rvndsngwn commented 2 days ago

To resolve the CORS issue, easiest way is use Firebase function or Appwrite cloud function. Both are have freemium plans.

Thank you, @bertrandgelinas , for providing the best guidance on how to use firebase functions.

Firebase: https://firebase.google.com/docs/functions Appwrite: https://appwrite.io/docs/products/functions/functions

https://github.com/appwrite/templates/tree/main/dart