This tutorial shows you how to:
- Place a marker when a user clicks on a location using a Google map
- Store those click locations in the Firebase Realtime Database
- Create a visual heatmap from the clicks stored in Firebase
By completing this tutorial you'll create an interactive map using realtime data, just like the one below. Try clicking it to build a heatmap.
What is Firebase?
Firebase is an application platform with many features. This tutorial uses its Realtime Database. Data is stored as JSON, is synced to all connected clients in real time, and is available even when your app goes offline.
Create your map
This may be similar to what you have done before, when getting started with the Google Maps JavaScript API.
Create a new file in a text editor and save it as index.html.
Copy the following code into the index.html file. The code loads the
Google Maps JavaScript API and makes the map fullscreen. It also loads the
visualization library, which you need later in the tutorial to create a heatmap.
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
html, body { height: 100%; margin: 0; padding: 0; }
#map { height: 100%; }
</style>
</head>
<body>
<div id="map"></div>
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY
&libraries=visualization&callback=initMap">
</script>
<script src="map.js"> </script>
</body>
</html>
You need an API key for your application. Click YOUR_API_KEY in the above code
sample, or follow the instructions to get
an API key. Replace YOUR_API_KEY with your application's API key.
Create a separate JavaScript file called map.js. In this file,
create a function to initialize the map object:
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
center: {lat: 0, lng: 0},
zoom: 3,
styles: [{
featureType: 'poi',
stylers: [{ visibility: 'off' }] // Turn off points of interest.
}, {
featureType: 'transit.station',
stylers: [{ visibility: 'off' }] // Turn off bus stations, train stations, etc.
}],
disableDoubleClickZoom: true
});
}
This application involves clicking on the map, so disabling points of interest and transit stations (which show an info window when clicked) makes it easier to use. Disabling zoom on double click also prevents accidental zooming by a user. For more information on map features, see the documentation.
The initMap() function is called from the script tag callback in the HTML file,
as shown below.
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY
&libraries=visualization&callback=initMap">
Open index.html in a web browser to view your Google map.
Add a marker when the user clicks the map
In this step, you add a listener for a click event. The listener creates a marker in the
position of the click. Add the listener inside the initMap() function, after
the code to create the map.
map.addListener('click', function(e) {
var marker = new google.maps.Marker({
position: {lat: e.latLng.lat(), lng: e.latLng.lng()},
map: map
});
});
Set up Firebase
In order to make this application collaborative, the clicks need to be stored in a external database that all users can access. The Firebase Realtime Database suits this purpose, and does not require any knowledge of SQL.
First, sign up for a free Firebase account.
If you are new to Firebase, you will see a new app with a name "My First App". However, if you
create a new app you are able to give the app a new name and custom Firebase URL ending in
firebaseIO.com. For example, you may name your app "Jane's Firebase Map" with the
URL https://janes-firebase-map.firebaseIO.com. You will use this URL to link the
database to your JavaScript application. To import the Firebase library, add this line between
the <head> tags of your HTML file.
<script src="https://cdn.firebase.com/js/client/2.2.1/firebase.js"></script>
Now you need a reference to your Firebase database. Add this line to the top
of map.js.
var firebase = new Firebase("<Your Firebase URL here>");
Store the click locations
Add this line inside the click event listener from the earlier step, to store the location of a click in your Firebase database.
firebase.push({lat: e.latLng.lat(), lng: e.latLng.lng()});
When you click on the map, the latitude and longitude of the click should now appear in your Firebase database. You can see this by logging into your Firebase account and navigating to the data tab of your app.
At this point, if someone else clicks on your map, that person sees a marker on the map and the data is stored in the Firebase database. However, you don't see a marker on the map. This is because markers are created on click events, client side only.
To fix this, remove the marker code from the click event listener.
Then, add the code below that listens for when a ‘child’ is added to your Firebase database and creates a marker when this occurs.
firebase.on("child_added", function(snapshot, prevChildKey) {
// Get latitude and longitude from the cloud.
var newPosition = snapshot.val();
// Create a google.maps.LatLng object for the position of the marker.
// A LatLng object literal (as above) could be used, but the heatmap
// in the next step requires a google.maps.LatLng object.
var latLng = new google.maps.LatLng(newPosition.lat, newPosition.lng);
// Place a marker at that location.
var marker = new google.maps.Marker({
position: latLng,
map: map
});
});
When an entry is added to the Firebase database, this function is called.
snapshot.val() gets the values that were added to the database and a LatLng object
is made from those values. A marker is then created in this position.
The location of the clicks persists even after the user closes the page. As a way to test the realtime collaborative functionality, open the page in two separate windows. The markers should appear on both in realtime.
At this stage, map.js should look like this:
// Reference to the Firebase database.
var firebase = new Firebase("<Your Firebase URL here>");
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
center: {lat: 0, lng: 0},
zoom: 3
});
// Add marker on user click
map.addListener('click', function(e) {
firebase.push({lat: e.latLng.lat(), lng: e.latLng.lng()});
});
firebase.on("child_added", function(snapshot, prevChildKey) {
// Get latitude and longitude from the cloud.
var newPosition = snapshot.val();
// Create a google.maps.LatLng object for the position of the marker.
// A LatLng object literal (as above) could be used, but the heatmap
// in the next step requires a google.maps.LatLng object.
var latLng = new google.maps.LatLng(newPosition.lat, newPosition.lng);
// Place a marker at that location.
var marker = new google.maps.Marker({
position: latLng,
map: map
});
});
}
Create a heatmap
The next step is to display the clicks as a heatmap, instead of individual markers. This provides a graphical view of the density of clicks, so that viewers can get an impression of the relative number of clicks in various locations on the map.
Create a heatmap inside your initMap() function.
// Create a heatmap.
var heatmap = new google.maps.visualization.HeatmapLayer({
data: [],
map: map,
radius: 8
});
Instead of creating a marker when a entry is added to the Firebase database, you need to add the point to the heatmap. Replace the marker code with the following line:
heatmap.getData().push(latLng);
The final map.js file looks like this:
// Reference to the Firebase Realtime Database.
var firebase = new Firebase("<Your Firebase URL here>");
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
center: {lat: 0, lng: 0},
zoom: 3
});
// Add marker on user click
map.addListener('click', function(e) {
firebase.push({lat: e.latLng.lat(), lng: e.latLng.lng()});
});
// Create a heatmap.
var heatmap = new google.maps.visualization.HeatmapLayer({
data: [],
map: map,
radius: 8
});
firebase.on("child_added", function(snapshot, prevChildKey) {
// Get latitude and longitude from Firebase.
var newPosition = snapshot.val();
// Create a google.maps.LatLng object for the position of the marker.
// A LatLng object literal (as above) could be used, but the heatmap
// in the next step requires a google.maps.LatLng object.
var latLng = new google.maps.LatLng(newPosition.lat, newPosition.lng);
heatmap.getData().push(latLng);
});
}
You now have a fully functional real-time application using Firebase and the Google Maps JavaScript API.
