> For the complete documentation index, see [llms.txt](https://manual.bubble.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://manual.bubble.io/help-guides/data/the-database/working-with-location-data.md).

# Working with location data

Maps and geolocation features in Bubble rely on Google APIs. Once your app uses your own domain, it will need your own Google API keys, added in the *Settings* tab, in the *General* section, under *General services API keys*. This guide covers how to obtain those keys, whether you're building for web, native mobile, or both.

{% hint style="info" %}
**Tip:** The Google API is used for timezones as well as geographic addresses. If you use *Current user's timezone* or any addresses anywhere in your app, it's worth setting up these keys.
{% endhint %}

{% embed url="<https://youtu.be/ouGT55o68ho>" %}
Our Academy tutorial on how to set up Google API keys
{% endembed %}

## Which keys you need

Which keys you set up depends on where your app runs. Each platform authenticates with Google using its own key, so a project that ships to web, iOS, and Android uses a separate key for each. You'll find all of them in the *Settings* tab, in the *General* section under *General services API keys*:

<table><thead><tr><th width="278.953125">Field</th><th width="113.1640625">Platform</th><th>Used for</th></tr></thead><tbody><tr><td><em>Google Maps API key</em></td><td>Web</td><td>Maps and location features in your web app.</td></tr><tr><td><em>Google Geocode API key</em></td><td>Web</td><td>Server-side geocoding, such as converting addresses to coordinates.</td></tr><tr><td><em>Google Maps API key for iOS</em></td><td>iOS</td><td>Maps and location features in your native iOS app.</td></tr><tr><td><em>Google Maps API key for Android</em></td><td>Android</td><td>Maps and location features in your native Android app.</td></tr></tbody></table>

Set up the keys for the platforms you're publishing to. A web-only app uses the first two, a mobile app uses a key for each mobile platform it ships to, and an app that runs everywhere uses all four. The project and enabled APIs are shared across platforms, so most of the setup below you do once, no matter how many platforms you're building for.

## Set up your project in the Google Cloud Console

First, you'll set up your app in the Google Cloud Console. This tells Google about your app and is how it knows which APIs your app is allowed to call.

Visit the [Google Cloud Console](https://console.cloud.google.com/). You'll need to log in, and you may also have to provide billing details, which Google requires.

Start by creating a *project* in Google that corresponds to your Bubble app.

<figure><img src="https://34394582-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M5sbzwG7CljeZdkntrL%2Fuploads%2F2OOHAQZbJXr53Bz0aRaN%2Fnew-cloud-console-project.png?alt=media&amp;token=644241bc-3805-407f-a0b7-b381031a94b4" alt="The Google Cloud Console&#x27;s Select a resource dialog, with a New project button in the top-right corner."><figcaption><p>In the Google Cloud Console, click New project to create a project for your app.</p></figcaption></figure>

{% hint style="info" %}
We recommend creating one project per app you are working on to keep your API keys, usage, and billing cleanly separated. That way, you can track each app's costs on its own, and a change to one app's keys won't affect any of your others.
{% endhint %}

With that project active (its name shows in the top bar), open the navigation menu in the upper-left corner and go to *APIs & Services*, then *Library*.

<figure><img src="https://34394582-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M5sbzwG7CljeZdkntrL%2Fuploads%2FrE3rFyh1ZISDeLNe0NLK%2Fenable-apis.png?alt=media&amp;token=d2c91ef7-20a5-436b-b637-938e980f9c47" alt="The Google Cloud API Library with &#x22;geocoding api&#x22; searched, showing result cards including the Geocoding API, Maps JavaScript API, and Places API (New)."><figcaption><p>Search the API Library for each API by name, then select it to enable it. Here we're searching for the Geocoding API.</p></figcaption></figure>

### Enable the APIs

In the library, search for each of the following APIs and enable them one at a time. These power the core maps and location features across every platform.

{% stepper %}
{% step %}

#### Geocoding API

Converts addresses into geographic coordinates (latitude and longitude), and coordinates back into readable addresses. This is what lets your app turn a typed address into a point on a map, or work out an address from a location.
{% endstep %}

{% step %}

#### Places API

Provides information about places, like businesses and points of interest, and powers address autocomplete as users type. This is what lets your app suggest and identify real-world locations.
{% endstep %}

{% step %}

#### Geolocation API

Determines a device's approximate location based on nearby cell towers and Wi-Fi signals, rather than a typed address. This is what lets your app work out where a user is.
{% endstep %}

{% step %}

#### Maps JavaScript API

Renders the interactive map in the browser. This is what actually draws the map, its tiles, and its markers in your web app.
{% endstep %}

{% step %}

#### Time Zone API

Returns the time zone for a given location. This is what lets your app work with a user's local time, including the *Current user's timezone* value.
{% endstep %}
{% endstepper %}

{% hint style="info" %}
If you're building a native mobile app, also enable the **Maps SDK for iOS**, the **Maps SDK for Android**, or both, depending on which platforms you're publishing to. These render the map on each native platform, the same way the Maps JavaScript API does on web.
{% endhint %}

## Create your keys

With your APIs enabled, you'll create a key for each platform you're building for. Every key is created the same way, from the **Credentials** page. What differs between them is how each one is *restricted*, since each platform proves it's allowed to use the key in a different way.

### Web keys

A web app uses two keys: a *Client* key for requests made from the browser, and a *Server* key for requests made server-side.

#### Client key

{% stepper %}
{% step %}

#### Create the key

On the **Credentials** page, click **+ Create credentials** and select **API key**. Rename the key to *Client*.

<figure><img src="https://34394582-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M5sbzwG7CljeZdkntrL%2Fuploads%2Fb1lQ4O8c5WN0ejmgir0p%2Fcredentials.png?alt=media&amp;token=8fe06a3a-e277-4ecc-b273-7033e0e084fb" alt="The Google Cloud navigation menu with APIs &#x26; Services selected, and its submenu open showing the Credentials option."><figcaption><p>To create your keys, open the navigation menu and go to APIs &#x26; Services, then Credentials.</p></figcaption></figure>
{% endstep %}

{% step %}

#### Add API restrictions

Under the key's API restrictions, select **Restrict key** and choose the Geocoding API, Places API, Geolocation API, Maps JavaScript API, and Time Zone API.
{% endstep %}

{% step %}

#### Add website restrictions

Under application restrictions, select **Websites** and add referrers in a format like the ones below, depending on your setup.

For a Bubble-hosted app:

* `*.appname.bubbleapps.io/*`
* `appname.bubbleapps.io/*`
* `https://appname.bubbleapps.io/*`
* `https://www.appname.bubbleapps.io/*`

For a custom domain:

* `*.yourdomain.com/*`
* `yourdomain.com/*`
* `https://yourdomain.com/*`
* `https://www.yourdomain.com/*`

For a subdomain:

* `*.subapp.yourdomain.com/*`
* `subapp.yourdomain.com/*`
* `https://subapp.yourdomain.com/*`
* `https://www.subapp.yourdomain.com/*`
  {% endstep %}

{% step %}

#### Save the key

Click **Save** to finish creating the Client key.
{% endstep %}
{% endstepper %}

{% hint style="info" %}
Website restrictions have limited wildcard support. You can use a wildcard (`*`) in place of a subdomain or path, such as `*.example.com`, but not in the middle of a URL.
{% endhint %}

#### Server key

{% stepper %}
{% step %}

#### Create the key

Click **+ Create credentials** again and select **API key**. Rename this one to *Server*.
{% endstep %}

{% step %}

#### Add API restrictions

Under the key's API restrictions, select **Restrict key** and choose the same APIs as the Client key.
{% endstep %}

{% step %}

#### Save the key

Click **Save**. The Server key doesn't need website restrictions, since it's used for server-side requests rather than requests from a browser.
{% endstep %}
{% endstepper %}

### iOS key

A native iOS app uses its own key, restricted to your app by its bundle ID, the same identifier you set when publishing to the App Store. A native app doesn't run on a web domain, so it's restricted this way instead of by website.

{% stepper %}
{% step %}

#### Create the key

On the **Credentials** page, click **+ Create credentials** and select **API key**. Rename it to *iOS*.
{% endstep %}

{% step %}

#### Restrict the key to iOS

Under application restrictions, select **iOS apps** and add your app's bundle ID.
{% endstep %}

{% step %}

#### Save the key

Click **Save** to finish creating the iOS key.
{% endstep %}
{% endstepper %}

### Android key

A native Android app uses its own key, restricted to your app by its package name and signing certificate. As with iOS, a native app isn't restricted by website.

{% stepper %}
{% step %}

#### Create the key

On the **Credentials** page, click **+ Create credentials** and select **API key**. Rename it to *Android*.
{% endstep %}

{% step %}

#### Restrict the key to Android

Under application restrictions, select **Android apps** and add your app's package name and SHA-1 signing certificate fingerprint.
{% endstep %}

{% step %}

#### Save the key

Click **Save** to finish creating the Android key.
{% endstep %}
{% endstepper %}

## Add your keys to Bubble

Your keys are now ready to use. In your Bubble editor, go to the *Settings* tab, in the *General* section, and find *General services API keys*. Add each key to the field that matches its platform.

<figure><img src="https://34394582-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M5sbzwG7CljeZdkntrL%2Fuploads%2Fr92ri7EMZ6QVNt8B96zv%2Fkeys.png?alt=media&amp;token=9a59eba5-4089-4a19-95e5-cccc8f4a017f" alt="The General services API keys section of Bubble&#x27;s Settings tab, with fields for the Google Geocode, Google Maps, Google Maps for iOS, and Google Maps for Android keys."><figcaption><p>Add each key to its matching field in the General services API keys section of the Settings tab.</p></figcaption></figure>

<table><thead><tr><th width="143.5625">Key</th><th>Field</th></tr></thead><tbody><tr><td><em>Client</em></td><td><em>Google Maps API key</em></td></tr><tr><td><em>Server</em></td><td><em>Google Geocode API key</em></td></tr><tr><td><em>iOS</em></td><td><em>Google Maps API key for iOS</em></td></tr><tr><td><em>Android</em></td><td><em>Google Maps API key for Android</em></td></tr></tbody></table>

## Further notes on the Google side

* Google's own instructions for setting up an API key are [here for Maps](https://developers.google.com/maps/documentation/javascript/get-api-key) and [here for Geocoding](https://developers.google.com/maps/documentation/geocoding/get-api-key). Since Google updates its interface from time to time, refer to their official documentation if anything looks different.
* To use these APIs, you may need to set up a billing account with Google Cloud and connect your Google project to it.
* Changes to a Google project's configuration can take a minute or so to take effect.

{% hint style="warning" %}
Because Bubble uses the Google Maps API, some inconsistencies in Google Maps data will show up in your app. For example, for some non-US addresses, the *city* field is actually the name of the neighbourhood or area. To help with this, try adding a map element (even a hidden one) that takes its value from a SearchBox input. The map places the pin correctly, and its *center* may then yield more accurate data about that location.
{% endhint %}
