Все готово!

Прежде чем приступить к разработке, ознакомьтесь с документацией для разработчиков.

Активация Google Maps JavaScript API

Чтобы помочь вам освоиться, мы покажем, как выполнить некоторые необходимые действия в консоли разработчика Google:

  1. Создание или выбор проекта
  2. Активация Google Maps JavaScript API и связанных служб
  3. Создание соответствующих ключей

Создание интерактивных пользовательских карт на платформе Firebase

Обзор

В этом руководстве показано, как создать интерактивную карту с помощью платформы приложений Firebase. Попробуйте нажать разные места на карте ниже, чтобы построить карту интенсивности.

Ниже приведен полный программный код, необходимый для создания карты в данном руководстве.

/**
* Reference to Firebase database.
* @const
*/
var firebase = new Firebase('https://fire-map-tutorial.firebaseio.com/');

/**
* Data object to be written to Firebase.
*/
var data = {
  sender: null,
  timestamp: null,
  lat: null,
  lng: null
};

function makeInfoBox(controlDiv, map) {
  // Set CSS for the control border.
  var controlUI = document.createElement('div');
  controlUI.style.boxShadow = 'rgba(0, 0, 0, 0.298039) 0px 1px 4px -1px';
  controlUI.style.backgroundColor = '#fff';
  controlUI.style.border = '2px solid #fff';
  controlUI.style.borderRadius = '2px';
  controlUI.style.marginBottom = '22px';
  controlUI.style.marginTop = '10px';
  controlUI.style.textAlign = 'center';
  controlDiv.appendChild(controlUI);

  // Set CSS for the control interior.
  var controlText = document.createElement('div');
  controlText.style.color = 'rgb(25,25,25)';
  controlText.style.fontFamily = 'Roboto,Arial,sans-serif';
  controlText.style.fontSize = '100%';
  controlText.style.padding = '6px';
  controlText.textContent = 'The map shows all clicks made in the last 10 minutes.';
  controlUI.appendChild(controlText);
}

/**
* Starting point for running the program. Authenticates the user.
* @param {function()} onAuthSuccess - Called when authentication succeeds.
*/
function initAuthentication(onAuthSuccess) {
  firebase.authAnonymously(function(error, authData) {
    if (error) {
      console.log('Login Failed!', error);
    } else {
      data.sender = authData.uid;
      onAuthSuccess();
    }
  }, {remember: 'sessionOnly'});  // Users will get a new id for every session.
}

/**
 * Creates a map object with a click listener and a heatmap.
 */
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 POI.
    },
    {
      featureType: 'transit.station',
      stylers: [{ visibility: 'off' }]  // Turn off bus, train stations etc.
    }],
    disableDoubleClickZoom: true,
    streetViewControl: false,
  });

  // Create the DIV to hold the control and call the makeInfoBox() constructor
  // passing in this DIV.
  var infoBoxDiv = document.createElement('div');
  makeInfoBox(infoBoxDiv, map);
  map.controls[google.maps.ControlPosition.TOP_CENTER].push(infoBoxDiv);

  // Listen for clicks and add the location of the click to firebase.
  map.addListener('click', function(e) {
    data.lat = e.latLng.lat();
    data.lng = e.latLng.lng();
    addToFirebase(data);
  });

  // Create a heatmap.
  var heatmap = new google.maps.visualization.HeatmapLayer({
    data: [],
    map: map,
    radius: 16
  });

  initAuthentication(initFirebase.bind(undefined, heatmap));
}

/**
 * Set up a Firebase with deletion on clicks older than expirySeconds
 * @param {!google.maps.visualization.HeatmapLayer} heatmap The heatmap to
 * which points are added from Firebase.
 */
function initFirebase(heatmap) {

  // 10 minutes before current time.
  var startTime = new Date().getTime() - (60 * 10 * 1000);

  // Reference to the clicks in Firebase.
  var clicks = firebase.child('clicks');

  // Listener for when a click is added.
  clicks.orderByChild('timestamp').startAt(startTime).on('child_added',
    function(snapshot) {

      // Get that click from firebase.
      var newPosition = snapshot.val();
      var point = new google.maps.LatLng(newPosition.lat, newPosition.lng);
      var elapsed = new Date().getTime() - newPosition.timestamp;

      // Add the point to  the heatmap.
      heatmap.getData().push(point);

      // Requests entries older than expiry time (10 minutes).
      var expirySeconds = Math.max(60 * 10 * 1000 - elapsed, 0);
      // Set client timeout to remove the point after a certain time.
      window.setTimeout(function() {
        // Delete the old point from the database.
        snapshot.ref().remove();
      }, expirySeconds);
    }
  );

  // Remove old data from the heatmap when a point is removed from firebase.
  clicks.on('child_removed', function(snapshot, prevChildKey) {
    var heatmapData = heatmap.getData();
    var i = 0;
    while (snapshot.val().lat != heatmapData.getAt(i).lat()
      || snapshot.val().lng != heatmapData.getAt(i).lng()) {
      i++;
    }
    heatmapData.removeAt(i);
  });
}

/**
 * Updates the last_message/ path with the current timestamp.
 * @param {function(Date)} addClick After the last message timestamp has been updated,
 *     this function is called with the current timestamp to add the
 *     click to the firebase.
 */
function getTimestamp(addClick) {
  // Reference to location for saving the last click time.
  var ref = firebase.child('last_message/' + data.sender);

  ref.onDisconnect().remove();  // Delete reference from firebase on disconnect.

  // Set value to timestamp.
  ref.set(Firebase.ServerValue.TIMESTAMP, function(err) {
    if (err) {  // Write to last message was unsuccessful.
      console.log(err);
    } else {  // Write to last message was successful.
      ref.once('value', function(snap) {
        addClick(snap.val());  // Add click with same timestamp.
      }, function(err) {
        console.warn(err);
      });
    }
  });
}

/**
 * Adds a click to firebase.
 * @param {Object} data The data to be added to firebase.
 *     It contains the lat, lng, sender and timestamp.
 */
function addToFirebase(data) {
  getTimestamp(function(timestamp) {
    // Add the new timestamp to the record data.
    data.timestamp = timestamp;
    var ref = firebase.child('clicks').push(data, function(err) {
      if (err) {  // Data was not written to firebase.
        console.warn(err);
      }
    });
  });
}
<div id="map"></div>
/* Always set the map height explicitly to define the size of the div
 * element that contains the map. */
#map {
  height: 100%;
}
/* Optional: Makes the sample page fill the window. */
html, body {
  height: 100%;
  margin: 0;
  padding: 0;
}
<!-- Replace the value of the key parameter with your own API key. -->
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&libraries=visualization&callback=initMap" async defer></script>
<script src="https://cdn.firebase.com/js/client/2.3.2/firebase.js"></script>

Попробуйте сделать это сами

Наведите указатель мыши на верхнюю правую часть блока кода, чтобы скопировать код или открыть его в JSFiddle.

<!DOCTYPE html>
<html>
  <head>
    <style>
      /* Always set the map height explicitly to define the size of the div
       * element that contains the map. */
      #map {
        height: 100%;
      }
      /* Optional: Makes the sample page fill the window. */
      html, body {
        height: 100%;
        margin: 0;
        padding: 0;
      }
    </style>
  </head>
  <body>
    <div id="map"></div>

    <script src="https://cdn.firebase.com/js/client/2.3.2/firebase.js"></script>
    <script>
      /**
      * Reference to Firebase database.
      * @const
      */
      var firebase = new Firebase('https://fire-map-tutorial.firebaseio.com/');

      /**
      * Data object to be written to Firebase.
      */
      var data = {
        sender: null,
        timestamp: null,
        lat: null,
        lng: null
      };

      function makeInfoBox(controlDiv, map) {
        // Set CSS for the control border.
        var controlUI = document.createElement('div');
        controlUI.style.boxShadow = 'rgba(0, 0, 0, 0.298039) 0px 1px 4px -1px';
        controlUI.style.backgroundColor = '#fff';
        controlUI.style.border = '2px solid #fff';
        controlUI.style.borderRadius = '2px';
        controlUI.style.marginBottom = '22px';
        controlUI.style.marginTop = '10px';
        controlUI.style.textAlign = 'center';
        controlDiv.appendChild(controlUI);

        // Set CSS for the control interior.
        var controlText = document.createElement('div');
        controlText.style.color = 'rgb(25,25,25)';
        controlText.style.fontFamily = 'Roboto,Arial,sans-serif';
        controlText.style.fontSize = '100%';
        controlText.style.padding = '6px';
        controlText.textContent = 'The map shows all clicks made in the last 10 minutes.';
        controlUI.appendChild(controlText);
      }

      /**
      * Starting point for running the program. Authenticates the user.
      * @param {function()} onAuthSuccess - Called when authentication succeeds.
      */
      function initAuthentication(onAuthSuccess) {
        firebase.authAnonymously(function(error, authData) {
          if (error) {
            console.log('Login Failed!', error);
          } else {
            data.sender = authData.uid;
            onAuthSuccess();
          }
        }, {remember: 'sessionOnly'});  // Users will get a new id for every session.
      }

      /**
       * Creates a map object with a click listener and a heatmap.
       */
      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 POI.
          },
          {
            featureType: 'transit.station',
            stylers: [{ visibility: 'off' }]  // Turn off bus, train stations etc.
          }],
          disableDoubleClickZoom: true,
          streetViewControl: false,
        });

        // Create the DIV to hold the control and call the makeInfoBox() constructor
        // passing in this DIV.
        var infoBoxDiv = document.createElement('div');
        makeInfoBox(infoBoxDiv, map);
        map.controls[google.maps.ControlPosition.TOP_CENTER].push(infoBoxDiv);

        // Listen for clicks and add the location of the click to firebase.
        map.addListener('click', function(e) {
          data.lat = e.latLng.lat();
          data.lng = e.latLng.lng();
          addToFirebase(data);
        });

        // Create a heatmap.
        var heatmap = new google.maps.visualization.HeatmapLayer({
          data: [],
          map: map,
          radius: 16
        });

        initAuthentication(initFirebase.bind(undefined, heatmap));
      }

      /**
       * Set up a Firebase with deletion on clicks older than expirySeconds
       * @param {!google.maps.visualization.HeatmapLayer} heatmap The heatmap to
       * which points are added from Firebase.
       */
      function initFirebase(heatmap) {

        // 10 minutes before current time.
        var startTime = new Date().getTime() - (60 * 10 * 1000);

        // Reference to the clicks in Firebase.
        var clicks = firebase.child('clicks');

        // Listener for when a click is added.
        clicks.orderByChild('timestamp').startAt(startTime).on('child_added',
          function(snapshot) {

            // Get that click from firebase.
            var newPosition = snapshot.val();
            var point = new google.maps.LatLng(newPosition.lat, newPosition.lng);
            var elapsed = new Date().getTime() - newPosition.timestamp;

            // Add the point to  the heatmap.
            heatmap.getData().push(point);

            // Requests entries older than expiry time (10 minutes).
            var expirySeconds = Math.max(60 * 10 * 1000 - elapsed, 0);
            // Set client timeout to remove the point after a certain time.
            window.setTimeout(function() {
              // Delete the old point from the database.
              snapshot.ref().remove();
            }, expirySeconds);
          }
        );

        // Remove old data from the heatmap when a point is removed from firebase.
        clicks.on('child_removed', function(snapshot, prevChildKey) {
          var heatmapData = heatmap.getData();
          var i = 0;
          while (snapshot.val().lat != heatmapData.getAt(i).lat()
            || snapshot.val().lng != heatmapData.getAt(i).lng()) {
            i++;
          }
          heatmapData.removeAt(i);
        });
      }

      /**
       * Updates the last_message/ path with the current timestamp.
       * @param {function(Date)} addClick After the last message timestamp has been updated,
       *     this function is called with the current timestamp to add the
       *     click to the firebase.
       */
      function getTimestamp(addClick) {
        // Reference to location for saving the last click time.
        var ref = firebase.child('last_message/' + data.sender);

        ref.onDisconnect().remove();  // Delete reference from firebase on disconnect.

        // Set value to timestamp.
        ref.set(Firebase.ServerValue.TIMESTAMP, function(err) {
          if (err) {  // Write to last message was unsuccessful.
            console.log(err);
          } else {  // Write to last message was successful.
            ref.once('value', function(snap) {
              addClick(snap.val());  // Add click with same timestamp.
            }, function(err) {
              console.warn(err);
            });
          }
        });
      }

      /**
       * Adds a click to firebase.
       * @param {Object} data The data to be added to firebase.
       *     It contains the lat, lng, sender and timestamp.
       */
      function addToFirebase(data) {
        getTimestamp(function(timestamp) {
          // Add the new timestamp to the record data.
          data.timestamp = timestamp;
          var ref = firebase.child('clicks').push(data, function(err) {
            if (err) {  // Data was not written to firebase.
              console.warn(err);
            }
          });
        });
      }
    </script>
    <script async defer
        src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=visualization&callback=initMap">
    </script>
  </body>
</html>

Начало работы

Используя программный код из данного руководства, можно разработать свою версию карты на Firebase. Для этого создайте в текстовом редакторе новый файл и сохраните его под именем index.html.

Для понимания программного кода, который можно добавить в этот файл, ознакомьтесь со следующими разделами.

Создание базовой карты

В этом разделе поясняется программный код, который устанавливает базовую карту. Процесс аналогичен порядку создания карт при начале работы с Google Maps JavaScript API.

Скопируйте программный код ниже в файл index.html. Этот программный код загружает Google Maps JavaScript API и устанавливает полноэкранный режим отображения карты. Он также загружает библиотеку Visualization, которая понадобится позже для создания карты интенсивности.

<!DOCTYPE html>
<html>
  <head>
    <style type="text/css">
      #map {
        height: 100%;
      }
      html, body {
        height: 100%;
        margin: 0;
        padding: 0;
      }
    </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>

    /**
     * The JavaScript code that creates the firebase map goes between the empty script tags below.
     */
    <script>firebasemap.js</script>

  </body>
</html>

В образце программного кода нажмите на YOUR_API_KEY либо следуйте инструкциям, чтобы получить ключ API. Замените YOUR_API_KEY ключом API вашего приложения.


В следующих разделах поясняется код JavaScript, который создает карту на Firebase. Код можно скопировать и сохранить в файл firebasemap.js, а затем указать имя файла между тегами script, как показано ниже.

<script>firebasemap.js</script>
Вы также можете вставить код непосредственно между тегами script, как показано в примере полного кода, приведенном в начале этого руководства.

Вставьте приведенный ниже код в файл firebasemap.js либо в пустую пару тегов script в файле index.html. Это отправная точка для выполнения программы, где создается функция, которая инициализирует объект карты.

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
  });
}

Для облегчения использования этой интерактивной карты интенсивности приведенный выше код отключает достопримечательности и промежуточные остановки (которые отображаются в информационном окне при нажатии). Он также отключает масштабирование двойным нажатием, чтобы предотвратить случайное масштабирование. Более подробные сведения о свойствах карты см. в документации.

После того, как API полностью загрузится, параметр обратного вызова в приведенном ниже теге script выполняет функцию initMap() в HTML-файле.

<script async defer
    src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY
    &libraries=visualization&callback=initMap">

Добавьте приведенный ниже код, чтобы создать текстовый элемент управления вверху карты.

  function makeInfoBox(controlDiv, map) {
    // Set CSS for the control border.
    var controlUI = document.createElement('div');
    controlUI.style.boxShadow = 'rgba(0, 0, 0, 0.298039) 0px 1px 4px -1px';
    controlUI.style.backgroundColor = '#fff';
    controlUI.style.border = '2px solid #fff';
    controlUI.style.borderRadius = '2px';
    controlUI.style.marginBottom = '22px';
    controlUI.style.marginTop = '10px';
    controlUI.style.textAlign = 'center';
    controlDiv.appendChild(controlUI);

    // Set CSS for the control interior.
    var controlText = document.createElement('div');
    controlText.style.color = 'rgb(25,25,25)';
    controlText.style.fontFamily = 'Roboto,Arial,sans-serif';
    controlText.style.fontSize = '100%';
    controlText.style.padding = '6px';
    controlText.innerText = 'The map shows all clicks made in the last 10 minutes.';
    controlUI.appendChild(controlText);
  }

Добавьте приведенный ниже код в функцию initMap после var map, чтобы загрузить текстовое поле.

  // Create the DIV to hold the control and call the makeInfoBox() constructor
  // passing in this DIV.
  var infoBoxDiv = document.createElement('div');
  var infoBox = new makeInfoBox(infoBoxDiv, map);
  infoBoxDiv.index = 1;
  map.controls[google.maps.ControlPosition.TOP_CENTER].push(infoBoxDiv);
Попробуйте сейчас

Чтобы посмотреть карту Google, которую создает код, откройте в браузере файл index.html.

Настройка Firebase

Чтобы это приложение можно было использовать совместно, необходимо сохранять нажатия во внешней базе данных, доступной для всех пользователей. Для этой задачи подходит работающая в режиме реального времени база данных Firebase, которая не требует никаких знаний SQL.

Прежде всего, зарегистрируйте бесплатную учетную запись Firebase. Если вы в Firebase впервые, то увидите новое приложение под названием "My First App". Если вы создаете новое приложение, ему можно дать новое название и собственный URL-адрес для Firebase, заканчивающийся на firebaseIO.com. Например, можно назвать свое приложение "Jane's Firebase Map" с URL-адресом https://janes-firebase-map.firebaseIO.com. Этот URL-адрес можно использовать для связывания базы данных со своим приложением JavaScript.

Добавьте приведенную ниже строку после пары тегов <head> в своем файле HTML, чтобы импортировать библиотеку Firebase.

<script src="https://cdn.firebase.com/js/client/2.3.2/firebase.js"></script>

Добавьте следующую строку в файл JavaScript:

var firebase = new Firebase("<Your Firebase URL here>");

Хранение в Firebase данных о нажатиях

В этом разделе поясняется код, который сохраняет в Firebase данные о нажатиях мышью на карте.

Для каждого нажатия мышью на карте приведенный ниже код создает глобальный объект данных и сохраняет его информацию в Firebase. В этом объекте записываются такие данные, как latLng (широта и долгота), метка времени нажатия, а также уникальный идентификатор браузера, в котором произведено нажатие.

/**
 * Data object to be written to Firebase.
 */
var data = {
  sender: null,
  timestamp: null,
  lat: null,
  lng: null
};

Приведенный ниже код записывает уникальный идентификатор сеанса для каждого нажатия, что в соответствии с правилами безопасности Firebase позволяет контролировать интенсивность трафика на карте.

/**
 * Starting point for running the program. Authenticates the user.
 * @param {function} Called when authentication succeeds.
 */
function initAuthentication(onAuthSuccess) {
  firebase.authAnonymously(function(error, authData) {
    if (error) {
      console.log('Login Failed!', error);
    } else {
      data.sender = authData.uid;
      onAuthSuccess();
    }
  }, {remember: 'sessionOnly'});  // Users will get a new id for every session.
}

Следующая часть кода следит за нажатиями на карте, которые создают дочерний объект в базе данных Firebase. Когда это происходит, функция snapshot.val() получает значения данных записи и создает новый объект LatLng.

// Listener for when a click is added - add it to the heatmap.
clicks.orderByChild('timestamp').startAt(startTime).on('child_added',
  function(snapshot) {
    var newPosition = snapshot.val();
    var point = new google.maps.LatLng(newPosition.lat, newPosition.lng);
    heatmap.getData().push(point);
  }
);

Приведенный ниже код настраивает Firebase на последовательную запись меток времени и удаление нажатий на карте, которые были совершены более 10 секунд назад в режиме реального времени.

/**
 * Set up a Firebase with deletion on clicks older than expirySeconds
 * @param {!google.maps.visualization.HeatmapLayer} heatmap The heatmap to
 * which points are added from Firebase.
 */
function initFirebase(heatmap) {

  // 10 minutes before current time.
  var startTime = new Date().getTime() - (60 * 10 * 1000);

  // Reference to the clicks in Firebase.
  var clicks = firebase.child('clicks');

  // Remove old clicks.
  clicks.orderByChild('timestamp').endAt(startTime).on('child_added',
    function(snapshot) {
      snapshot.ref().remove();
    }
  );

}

/**
 * Adds a click to firebase.
 * @param {Object} data The data to be added to firebase.
 *     It contains the lat, lng, sender and timestamp.
 */
function addToFirebase(data) {
  getTimestamp(function(timestamp) {
    // Add the new timestamp to the record data.
    data.timestamp = timestamp;
    var ref = firebase.child('clicks').push(data, function(err) {
      if (err) {  // Data was not written to firebase.
        console.log(err);
      }
    });
  });
}

/**
 * Also called each time the map is clicked.
 * Updates the last_message/ path with the current timestamp.
 * @param {function(Date)} addClick After the last message timestamp has been updated,
 *     this function is called with the current timestamp to add the
 *     click to the firebase.
 */
function getTimestamp(addClick) {
  // Reference to location for saving the last click time.
  var ref = firebase.child('last_message/' + data.sender);

  ref.onDisconnect().remove();  // Delete reference from firebase on disconnect.

  // Set value to timestamp.
  ref.set(Firebase.ServerValue.TIMESTAMP, function(err) {
    if (err) {  // Write to last message was unsuccessful.
      console.log(err);
    } else {  // Write to last message was successful.
      ref.once('value', function(snap) {
        addClick(snap.val());  // Add click with same timestamp.
      }, function(err) {
        console.log(err);
      });
    }
  });
}

Скопируйте весь код JavaScript из этого раздела в файл firebasemap.js.

Создание карты интенсивности

Следующим шагом является создание карты интенсивности, которая дает пользователям графическое представление относительного числа нажатий в различных местах карты. Подробнее смотрите руководство по картам интенсивности.

Чтобы создать карту интенсивности, добавьте приведенный ниже код в функцию initMap().

// Create a heatmap.
var heatmap = new google.maps.visualization.HeatmapLayer({
  data: [],
  map: map,
  radius: 16
});

Приведенный ниже код запускает функции initFirebase, addToFirebase и getTimestamp.

initAuthentication(initFirebase.bind(undefined, heatmap));

Далее, замените код маркера строкой ниже, чтобы отобразить записи из базы данных Firebase как точки на этой карте интенсивности.

heatmap.getData().push(point);

Попробуйте сейчас

Обновите в веб-браузере файл index.html. Вы должны увидеть, как появляются точки на карте, когда пользователи нажимают ее из других браузеров.

Создание точек на карте интенсивности

Обратите внимание, что если вы нажмете карту интенсивности, на ней всё еще не будут созданы точки.

Приведенный ниже код добавляет блок прослушивания в initMap() после кода, который создает карту. Этот код считывает данные каждого нажатия, сохраняет место вашего нажатия в базе данных Firebase и показывает точки на карте интенсивности.

// Listen for clicks and add the location of the click to firebase.
map.addListener('click', function(e) {
  data.lat = e.latLng.lat();
  data.lng = e.latLng.lng();
  addToFirebase(data);
});

Попробуйте сейчас

Нажмите разные места на карте, чтобы создать точки на карте интенсивности.

Теперь у вас есть полнофункциональное приложение в режиме реального времени, использующее Firebase и Google Maps JavaScript API.

Когда вы нажимаете карту интенсивности, широта и долгота точки нажатия теперь должны появиться в базе данных Firebase. Это можно увидеть, если войти в учетную запись Firebase и перейти на вкладку данных вашего приложения. Теперь, когда кто-то нажмет вашу карту, вы и этот человек увидите точки на карте. Расположение нажатий останется даже после того, как пользователь закроет страницу. Для проверки функциональности совместного использования в режиме реального времени откройте страницу в двух отдельных окнах. Маркеры должны появляться в реальном времени в обоих окнах.

Подробнее

Firebase является платформой приложений, которая хранит данные в формате JSON и синхронизирует их со всеми подключенными клиентами в режиме реального времени. Она доступна даже тогда, когда ваше приложение отключается от сети. Это руководство использует базу данных в режиме реального времени.

Оставить отзыв о...

Текущей странице
Google Maps JavaScript API
Google Maps JavaScript API
Нужна помощь? Обратитесь в службу поддержки.