نقشه برداری همزمان با Firebase

بررسی اجمالی

این آموزش به شما نشان می دهد که چگونه با استفاده از پلت فرم برنامه Firebase یک نقشه تعاملی ایجاد کنید. برای ساختن یک نقشه حرارتی، روی مکان های مختلف روی نقشه زیر کلیک کنید.

بخش زیر کل کد مورد نیاز برای ایجاد نقشه را در این آموزش نمایش می دهد.

/**
 * Firebase config block.
 */
var config = {
  apiKey: 'AIzaSyDX-tgWqPmTme8lqlFn2hIsqwxGL6FYPBY',
  authDomain: 'maps-docs-team.firebaseapp.com',
  databaseURL: 'https://maps-docs-team.firebaseio.com',
  projectId: 'maps-docs-team',
  storageBucket: 'maps-docs-team.appspot.com',
  messagingSenderId: '285779793579'
};

firebase.initializeApp(config);

/**
 * 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.auth().signInAnonymously().catch(function(error) {
          console.log(error.code + ', ' + error.message);
        }, {remember: 'sessionOnly'});

        firebase.auth().onAuthStateChanged(function(user) {
          if (user) {
            data.sender = user.uid;
            onAuthSuccess();
          } else {
            // User is signed out.
          }
        });
      }

      /**
       * 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 expiryMs
       * @param {!google.maps.visualization.HeatmapLayer} heatmap The heatmap to
       */
      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.database().ref('clicks');

        // Listen for clicks and add them to the heatmap.
        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 elapsedMs = Date.now() - newPosition.timestamp;

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

            // Request entries older than expiry time (10 minutes).
            var expiryMs = Math.max(60 * 10 * 1000 - elapsedMs, 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();
            }, expiryMs);
          }
        );

        // 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.database().ref('last_message/' + data.sender);

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

        // Set value to timestamp.
        ref.set(firebase.database.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.database().ref('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" defer></script>
<script src="https://www.gstatic.com/firebasejs/5.3.0/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://www.gstatic.com/firebasejs/5.3.0/firebase-app.js"></script>
    <script src="https://www.gstatic.com/firebasejs/5.3.0/firebase-auth.js"></script>
    <script src="https://www.gstatic.com/firebasejs/5.3.0/firebase-database.js"></script>
    <script>
/**
 * Firebase config block.
 */
var config = {
  apiKey: 'AIzaSyDX-tgWqPmTme8lqlFn2hIsqwxGL6FYPBY',
  authDomain: 'maps-docs-team.firebaseapp.com',
  databaseURL: 'https://maps-docs-team.firebaseio.com',
  projectId: 'maps-docs-team',
  storageBucket: 'maps-docs-team.appspot.com',
  messagingSenderId: '285779793579'
};

firebase.initializeApp(config);

/**
 * 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.auth().signInAnonymously().catch(function(error) {
          console.log(error.code + ', ' + error.message);
        }, {remember: 'sessionOnly'});

        firebase.auth().onAuthStateChanged(function(user) {
          if (user) {
            data.sender = user.uid;
            onAuthSuccess();
          } else {
            // User is signed out.
          }
        });
      }

      /**
       * 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 expiryMs
       * @param {!google.maps.visualization.HeatmapLayer} heatmap The heatmap to
       */
      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.database().ref('clicks');

        // Listen for clicks and add them to the heatmap.
        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 elapsedMs = Date.now() - newPosition.timestamp;

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

            // Request entries older than expiry time (10 minutes).
            var expiryMs = Math.max(60 * 10 * 1000 - elapsedMs, 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();
            }, expiryMs);
          }
        );

        // 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.database().ref('last_message/' + data.sender);

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

        // Set value to timestamp.
        ref.set(firebase.database.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.database().ref('clicks').push(data, function(err) {
            if (err) {  // Data was not written to firebase.
              console.warn(err);
            }
          });
        });
      }
    </script>
    <script defer
        src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=visualization&callback=initMap">
    </script>
  </body>
</html>

شروع شدن

با استفاده از کد موجود در این آموزش می توانید نسخه خود از نقشه Firebase را توسعه دهید. برای شروع این کار، یک فایل جدید در یک ویرایشگر متن ایجاد کنید و آن را به عنوان index.html ذخیره کنید.

برای درک کدهایی که می توانید به این فایل اضافه کنید، بخش های زیر را بخوانید.

ایجاد یک نقشه اولیه

این بخش کدی را که یک نقشه پایه را تنظیم می کند توضیح می دهد. این ممکن است شبیه نحوه ایجاد نقشه‌ها هنگام شروع با Maps JavaScript API باشد.

کد زیر را در فایل index.html خود کپی کنید. این کد Maps JavaScript API را بارگیری می کند و نقشه را تمام صفحه می کند. همچنین کتابخانه تجسم را بارگیری می کند، که بعداً در آموزش برای ایجاد یک نقشه حرارتی به آن نیاز دارید.

<!DOCTYPE html>
<html>
  <head>
    <style>
      #map {
        height: 100%;
      }
      html, body {
        height: 100%;
        margin: 0;
        padding: 0;
      }
    </style>
  </head>
  <body>
    <div id="map"></div>
    <script defer
        src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY
        &libraries=visualization&callback=initMap">
    </script>

    <script>
      // The JavaScript code that creates the Firebase map goes here.
    </script>

  </body>
</html>

روی YOUR_API_KEY در نمونه کد کلیک کنید، یا دستورالعمل‌ها را برای دریافت یک کلید API دنبال کنید. کلید API برنامه خود را جایگزین YOUR_API_KEY کنید.

بخش های بعدی کد جاوا اسکریپت را که نقشه Firebase را ایجاد می کند توضیح می دهد. می‌توانید کد را در فایل firebasemap.js کپی و ذخیره کنید و آن را بین تگ‌های اسکریپت مانند زیر ارجاع دهید.

<script>firebasemap.js</script>

همچنین، می‌توانید مستقیماً کد را در تگ‌های اسکریپت مانند کد نمونه کامل در ابتدای این آموزش وارد کنید.

کد زیر را به فایل firebasemap.js یا بین تگ های خالی اسکریپت فایل 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,
    streetViewControl: false
  });
}

برای سهولت استفاده از این نقشه حرارتی قابل کلیک، کد بالا از سبک نقشه برای غیرفعال کردن نقاط دیدنی و ایستگاه های حمل و نقل استفاده می کند (که با کلیک کردن، پنجره اطلاعاتی را نمایش می دهند). همچنین برای جلوگیری از بزرگنمایی تصادفی، زوم را با دوبار کلیک غیرفعال می کند. درباره طراحی نقشه خود بیشتر بخوانید.

پس از بارگیری کامل API، پارامتر callback در تگ اسکریپت زیر تابع initMap() را در فایل HTML اجرا می کند.

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

کد زیر را برای ایجاد کنترل متن در بالای نقشه اضافه کنید.

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);
اکنون آن را امتحان کنید

برای مشاهده نقشه گوگل که کد ایجاد می کند، فایل index.html را در یک مرورگر وب باز کنید.

راه اندازی Firebase

به منظور ایجاد مشترک این برنامه، باید کلیک ها را در یک پایگاه داده خارجی ذخیره کنید که همه کاربران بتوانند به آن دسترسی داشته باشند. پایگاه داده بیدرنگ Firebase برای این منظور مناسب است و نیازی به دانش SQL ندارد.

ابتدا بدون هیچ هزینه ای برای یک حساب Firebase ثبت نام کنید . اگر تازه وارد Firebase هستید، یک برنامه جدید با نام «اولین برنامه من» مشاهده خواهید کرد. اگر برنامه جدیدی ایجاد می‌کنید، می‌توانید به آن یک نام جدید و یک URL Firebase سفارشی که به firebaseIO.com ختم می‌شود، بدهید. برای مثال، می‌توانید نام برنامه خود را با URL https://janes-firebase-map.firebaseIO.com "Jane's Firebase Map" بگذارید. می توانید از این URL برای پیوند دادن پایگاه داده به برنامه جاوا اسکریپت خود استفاده کنید.

خط زیر را بعد از تگ های <head> فایل HTML خود اضافه کنید تا کتابخانه Firebase را وارد کنید.

<script src="www.gstatic.com/firebasejs/5.3.0/firebase.js"></script>

خط زیر را به فایل جاوا اسکریپت خود اضافه کنید:

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()} onAuthSuccess - Called when authentication succeeds.
*/
function initAuthentication(onAuthSuccess) {
  firebase.auth().signInAnonymously().catch(function(error) {
      console.log(error.code + ", " + error.message);
  }, {remember: 'sessionOnly'});

  firebase.auth().onAuthStateChanged(function(user) {
    if (user) {
      data.sender = user.uid;
      onAuthSuccess();
    } else {
      // User is signed out.
    }
  });
}

بخش بعدی کد زیر به کلیک‌ها روی نقشه گوش می‌دهد که یک «فرزند» به پایگاه داده Firebase شما اضافه می‌کند. هنگامی که این اتفاق می افتد، تابع snapshot.val() مقادیر داده ورودی را دریافت می کند و یک شی LatLng جدید ایجاد می کند.

// Listen for clicks and add them 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 را تنظیم می کند:

  • به کلیک روی نقشه گوش دهید. هنگامی که یک کلیک رخ می دهد، برنامه یک مهر زمانی ثبت می کند، سپس یک "فرزند" به پایگاه داده 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.database().ref('clicks');

  // Listen for clicks and add them to the heatmap.
  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 elapsedMs = Date.now() - newPosition.timestamp;

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

      // Request entries older than expiry time (10 minutes).
      var expiryMs = 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();
      }, expiryMs);
    }
  );

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

تمام کدهای جاوا اسکریپت موجود در این بخش را در فایل 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));

توجه داشته باشید که اگر روی نقشه حرارتی کلیک کنید، هنوز امتیاز ایجاد نمی کند. برای ایجاد نقاط روی نقشه، باید یک شنونده نقشه راه اندازی کنید.

ایجاد نقاط روی نقشه حرارتی

کد زیر یک شنونده در داخل 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 و Maps JavaScript API دارید.

وقتی روی نقشه حرارتی کلیک می‌کنید، اکنون باید طول و عرض جغرافیایی کلیک در پایگاه داده Firebase ظاهر شود. با ورود به حساب Firebase خود و رفتن به برگه داده برنامه خود می توانید این را ببینید. در این مرحله، اگر شخص دیگری روی نقشه شما کلیک کند، شما و همچنین آن شخص، می توانید نقاط روی نقشه را ببینید. مکان کلیک‌ها حتی پس از بستن صفحه توسط کاربر باقی می‌ماند. به عنوان راهی برای آزمایش عملکرد مشارکتی بلادرنگ، صفحه را در دو پنجره جداگانه باز کنید. نشانگرها باید در هر دو به صورت بلادرنگ ظاهر شوند.

بیشتر بدانید

Firebase یک پلتفرم کاربردی است که داده‌ها را به صورت JSON ذخیره می‌کند و با همه کلاینت‌های متصل به صورت بلادرنگ همگام‌سازی می‌کند. حتی زمانی که برنامه شما آفلاین است نیز در دسترس است. این آموزش از پایگاه داده بیدرنگ خود استفاده می کند.