Firebase AppCheck এবং reCAPTCHA দিয়ে Places API অনুরোধগুলিকে যাচাই করুন,Firebase AppCheck এবং reCAPTCHA দিয়ে Places API অনুরোধগুলিকে বৈধ করুন

১. শুরু করার আগে

আপনার ওয়েব অ্যাপ্লিকেশনের সাথে ব্যবহারকারীদের মিথস্ক্রিয়ার বৈধতা নিশ্চিত করতে, আপনি ব্যবহারকারীর সেশন যাচাই করার জন্য reCAPTCHA JWT টোকেন ব্যবহার করে Firebase App Check প্রয়োগ করবেন। এই সেটআপটি আপনাকে ক্লায়েন্ট অ্যাপ্লিকেশন থেকে Places API (New) -তে করা অনুরোধগুলি নিরাপদে পরিচালনা করতে সক্ষম করবে।

b40cfddb731786fa.png

লাইভ লিঙ্ক

আপনি যা নির্মাণ করবেন।

এটি দেখানোর জন্য, আপনি এমন একটি ওয়েব অ্যাপ তৈরি করবেন যা লোড হওয়ার সাথে সাথে একটি মানচিত্র প্রদর্শন করবে। এটি ফায়ারবেস এসডিকে (Firebase SDK) ব্যবহার করে গোপনে একটি reCAPTCHA টোকেনও তৈরি করবে। এরপর এই টোকেনটি আপনার Node.js সার্ভারে পাঠানো হবে, যেখানে প্লেসেস এপিআই (Places API)-তে যেকোনো অনুরোধ পাঠানোর আগে ফায়ারবেস (Firebase) সেটিকে যাচাই করে নেবে।

টোকেনটি বৈধ হলে, Firebase App Check সেটির মেয়াদ শেষ না হওয়া পর্যন্ত তা সংরক্ষণ করবে, ফলে প্রতিটি ক্লায়েন্ট অনুরোধের জন্য নতুন টোকেন তৈরি করার প্রয়োজন হবে না। টোকেনটি অবৈধ হলে, একটি নতুন টোকেন পাওয়ার জন্য ব্যবহারকারীকে পুনরায় reCAPTCHA যাচাইকরণ সম্পন্ন করতে বলা হবে।

২. পূর্বশর্তসমূহ

এই কোডল্যাবটি সম্পন্ন করতে আপনাকে নিচের বিষয়গুলো সম্পর্কে ভালোভাবে জানতে হবে। daea823b6bc38b67.png

প্রয়োজনীয় গুগল ক্লাউড পণ্যসমূহ

  • গুগল ক্লাউড ফায়ারবেস অ্যাপ চেক : টোকেন ব্যবস্থাপনার জন্য ডাটাবেস
  • গুগল রিক্যাপচা (Google reCAPTCHA) : টোকেন তৈরি এবং যাচাইকরণ। এটি ওয়েবসাইটে মানুষ এবং বট-এর মধ্যে পার্থক্য করার জন্য ব্যবহৃত একটি টুল। এটি ব্যবহারকারীর আচরণ, ব্রাউজারের বৈশিষ্ট্য এবং নেটওয়ার্কের তথ্য বিশ্লেষণ করে একটি স্কোর তৈরি করে, যা ব্যবহারকারীটি বট হওয়ার সম্ভাবনা নির্দেশ করে। স্কোর যথেষ্ট বেশি হলে, ব্যবহারকারীকে মানুষ হিসেবে গণ্য করা হয় এবং আর কোনো পদক্ষেপের প্রয়োজন হয় না। স্কোর কম হলে, ব্যবহারকারীর পরিচয় নিশ্চিত করার জন্য একটি ক্যাপচা (CAPTCHA) পাজল দেখানো হতে পারে। এই পদ্ধতিটি প্রচলিত ক্যাপচা পদ্ধতির চেয়ে কম হস্তক্ষেপমূলক, যা ব্যবহারকারীর অভিজ্ঞতাকে আরও মসৃণ করে তোলে।
  • (ঐচ্ছিক) গুগল ক্লাউড অ্যাপ ইঞ্জিন : ডেপ্লয়মেন্ট এনভায়রনমেন্ট।

প্রয়োজনীয় গুগল ম্যাপস প্ল্যাটফর্ম পণ্যসমূহ

এই কোডল্যাবে, আপনি গুগল ম্যাপস প্ল্যাটফর্মের নিম্নলিখিত পণ্যগুলো ব্যবহার করবেন:

এই কোডল্যাবের জন্য অন্যান্য প্রয়োজনীয়তা

এই কোডল্যাবটি সম্পন্ন করতে আপনার নিম্নলিখিত অ্যাকাউন্ট, পরিষেবা এবং টুলগুলির প্রয়োজন হবে:

  • বিলিং সক্ষম করা একটি গুগল ক্লাউড প্ল্যাটফর্ম অ্যাকাউন্ট
  • একটি গুগল ম্যাপস প্ল্যাটফর্ম এপিআই কী, যেখানে ম্যাপস জাভাস্ক্রিপ্ট এপিআই এবং প্লেসেস সক্রিয় করা আছে।
  • জাভাস্ক্রিপ্ট, এইচটিএমএল এবং সিএসএস সম্পর্কে প্রাথমিক জ্ঞান
  • Node.js সম্পর্কে প্রাথমিক জ্ঞান
  • আপনার পছন্দের একটি টেক্সট এডিটর বা আইডিই

৩. প্রস্তুত হন

গুগল ম্যাপস প্ল্যাটফর্ম সেট আপ করুন

আপনার যদি আগে থেকে একটি Google Cloud Platform অ্যাকাউন্ট এবং বিলিং সক্ষম করা কোনো প্রজেক্ট না থাকে, তাহলে একটি বিলিং অ্যাকাউন্ট ও প্রজেক্ট তৈরি করার জন্য অনুগ্রহ করে “ Getting Started with Google Maps Platform” গাইডটি দেখুন।

  1. ক্লাউড কনসোলে , প্রজেক্ট ড্রপ-ডাউন মেনুতে ক্লিক করুন এবং এই কোডল্যাবের জন্য যে প্রজেক্টটি ব্যবহার করতে চান সেটি নির্বাচন করুন।

e7ffad81d93745cd.png

  1. এই কোডল্যাবের জন্য প্রয়োজনীয় গুগল ম্যাপস প্ল্যাটফর্ম এপিআই এবং এসডিকে-গুলো গুগল ক্লাউড মার্কেটপ্লেস থেকে সক্রিয় করুন। এটি করার জন্য, এই ভিডিও অথবা এই ডকুমেন্টেশনে দেওয়া ধাপগুলো অনুসরণ করুন।
  2. ক্লাউড কনসোলের ক্রেডেনশিয়ালস পেজ থেকে একটি এপিআই কী তৈরি করুন। আপনি এই ভিডিও বা এই ডকুমেন্টেশনের ধাপগুলো অনুসরণ করতে পারেন। গুগল ম্যাপস প্ল্যাটফর্মে করা সমস্ত অনুরোধের জন্য একটি এপিআই কী প্রয়োজন।

অ্যাপ্লিকেশন ডিফল্ট ক্রেডেনশিয়াল

আপনি আপনার Firebase প্রজেক্টের সাথে ইন্টারঅ্যাক্ট করতে এবং Places API-তে রিকোয়েস্ট পাঠাতে Firebase Admin SDK ব্যবহার করবেন এবং এটি কাজ করার জন্য আপনাকে বৈধ ক্রেডেনশিয়াল প্রদান করতে হবে।

অনুরোধ পাঠানোর জন্য আপনার সার্ভারকে প্রমাণীকরণ করতে আমরা এডিসি অথেন্টিকেশন (অটোমেটিক ডিফল্ট ক্রেডেনশিয়ালস) ব্যবহার করব। বিকল্পভাবে (যা সুপারিশ করা হয় না), আপনি একটি সার্ভিস অ্যাকাউন্ট তৈরি করে আপনার কোডের মধ্যে ক্রেডেনশিয়ালস সংরক্ষণ করতে পারেন।

সংজ্ঞা : অ্যাপ্লিকেশন ডিফল্ট ক্রেডেনশিয়ালস (ADC) হলো গুগল ক্লাউডের একটি ব্যবস্থা, যা ক্রেডেনশিয়ালস স্পষ্টভাবে পরিচালনা না করেই আপনার অ্যাপ্লিকেশনগুলোকে স্বয়ংক্রিয়ভাবে প্রমাণীকরণের জন্য ব্যবহৃত হয়। এটি বিভিন্ন স্থানে (যেমন এনভায়রনমেন্ট ভেরিয়েবল, সার্ভিস অ্যাকাউন্ট ফাইল বা গুগল ক্লাউড মেটাডেটা সার্ভার) ক্রেডেনশিয়ালস খোঁজে এবং প্রথমে যেটি খুঁজে পায়, সেটিই ব্যবহার করে।

  • আপনার টার্মিনালে নিচের কমান্ডটি ব্যবহার করুন, যা আপনার অ্যাপ্লিকেশনগুলোকে বর্তমানে লগ-ইন করা ব্যবহারকারীর পক্ষ থেকে নিরাপদে গুগল ক্লাউড রিসোর্স অ্যাক্সেস করার অনুমতি দেবে:
gcloud auth application-default login
  • আপনি রুটে একটি .env ফাইল তৈরি করবেন যা একটি গুগল ক্লাউড প্রজেক্ট ভেরিয়েবল নির্দিষ্ট করবে:
GOOGLE_CLOUD_PROJECT="your-project-id"

একটি পরিষেবা অ্যাকাউন্ট তৈরি করুন

  • গুগল ম্যাপস প্ল্যাটফর্ম ট্যাব > "+ক্রেডেনশিয়াল তৈরি করুন" > পরিষেবা অ্যাকাউন্ট
  • Firebase AppCheck Admin রোলটি যোগ করুন, তারপর আপনার টাইপ করা সার্ভিস অ্যাকাউন্টের নামটি ইনপুট করুন, যেমন: firebase-appcheck-codelab@yourproject.iam.gserviceaccount.com

যোগ্যতা

  • তৈরি করা পরিষেবা অ্যাকাউন্টে ক্লিক করুন
  • KEYS ট্যাবে গিয়ে একটি Key তৈরি করুন > JSON > ডাউনলোড করা json ক্রেডেনশিয়ালগুলি সংরক্ষণ করুন। স্বয়ংক্রিয়ভাবে ডাউনলোড হওয়া xxx.json ফাইলটি আপনার রুট ফোল্ডারে সরান।
  • (পরবর্তী অধ্যায়) nodejs ফাইল server.js-এ এটিকে সঠিকভাবে নামকরণ করুন (firebase-credentials.json)

৪. ফায়ারবেস অ্যাপচেক ইন্টিগ্রেশন

আপনি ফায়ারবেস কনফিগারেশনের বিবরণ এবং reCAPTCHA গোপন কীগুলি পাবেন।

আপনি সেগুলো ডেমো অ্যাপ্লিকেশনে পেস্ট করে সার্ভারটি চালু করবেন।

ফায়ারবেসে একটি অ্যাপ্লিকেশন তৈরি করুন

ইতিমধ্যে তৈরি করা গুগল ক্লাউড প্রজেক্টটি নির্বাচন করুন (আপনাকে নির্দিষ্ট করতে হতে পারে: "প্যারেন্ট রিসোর্স নির্বাচন করা হচ্ছে")

a6d171c6d7e98087.pnga16010ba102cc90b.png

  • উপরের বাম দিকের মেনু (গিয়ার আইকন) থেকে একটি অ্যাপ্লিকেশন যোগ করুন।

18e5a7993ad9ea53.png4632158304652118.png

ফায়ারবেস প্রারম্ভিক কোড

  • ক্লায়েন্ট সাইডের জন্য firebase ইনিশিয়ালাইজেশন কোডটি সংরক্ষণ করে script.js (পরবর্তী অধ্যায়)-এ পেস্ট করুন।

f10dcf6f5027e9f0.png

  • Firebase-কে reCAPTCHA v3 টোকেন ব্যবহার করার অনুমতি দিতে আপনার অ্যাপটি নিবন্ধন করুন।

https://console.firebase.google.com /u/0/project/YOUR_PROJECT/appcheck/apps

da7efe203ce4142c.png

  • reCAPTCHA নির্বাচন করুন → reCAPTCHA ওয়েবসাইটে একটি কী তৈরি করুন (সঠিক ডোমেইন কনফিগার করা সহ: অ্যাপ ডেভেলপমেন্টের জন্য লোকালহোস্ট)

b47eab131617467.pnge6bddef9d5cf5460.png

  • Firebase AppCheck-এ reCAPTCHA Secret পেস্ট করুন।

a63bbd533a1b5437.png

  • অ্যাপের স্ট্যাটাস সবুজ হয়ে যাওয়া উচিত

4f7962b527b78ee5.png

৫. ডেমো অ্যাপ্লিকেশন

  • ক্লায়েন্ট ওয়েব অ্যাপ: এইচটিএমএল, জাভাস্ক্রিপ্ট, সিএসএস ফাইল
  • সার্ভার: Node.js ফাইল
  • পরিবেশ (.env): এপিআই কী
  • কনফিগারেশন (app.yaml): গুগল অ্যাপ ইঞ্জিন ডেপ্লয়মেন্ট সেটিংস

নোড.জেএস সেটআপ:

  • নেভিগেট করুন : আপনার টার্মিনাল খুলুন এবং আপনার ক্লোন করা প্রজেক্টের রুট ডিরেক্টরিতে যান।
  • Node.js ইনস্টল করুন (প্রয়োজন হলে) : ভার্সন ১৮ বা তার উচ্চতর সংস্করণ।
node -v  # Check installed version
  • প্রজেক্ট শুরু করা: একটি নতুন Node.js প্রজেক্ট শুরু করতে নিম্নলিখিত কমান্ডটি চালান, সমস্ত সেটিংস ডিফল্ট রাখুন:
npm init 
  • প্রয়োজনীয় ডিপেন্ডেন্সি ইনস্টল করুন: প্রজেক্টের জন্য প্রয়োজনীয় ডিপেন্ডেন্সিগুলো ইনস্টল করতে নিম্নলিখিত কমান্ডটি ব্যবহার করুন:
npm install @googlemaps/places firebase-admin express axios dotenv

কনফিগারেশন: গুগল ক্লাউড প্রজেক্টের জন্য এনভায়রনমেন্ট ভেরিয়েবল

  • এনভায়রনমেন্ট ফাইল তৈরি: আপনার প্রোজেক্টের রুট ডিরেক্টরিতে .env নামে একটি ফাইল তৈরি করুন। এই ফাইলে সংবেদনশীল কনফিগারেশন ডেটা সংরক্ষণ করা হবে এবং এটি ভার্সন কন্ট্রোলে কমিট করা উচিত নয়।
  • এনভায়রনমেন্ট ভেরিয়েবল যোগ করুন: .env ফাইলটি খুলুন এবং প্লেসহোল্ডারগুলির জায়গায় আপনার গুগল ক্লাউড প্রজেক্টের আসল মান বসিয়ে নিম্নলিখিত ভেরিয়েবলগুলি যোগ করুন:
# Google Cloud Project ID
GOOGLE_CLOUD_PROJECT="your-cloud-project-id"

# reCAPTCHA Keys (obtained in previous steps) 
RECAPTCHA_SITE_KEY="your-recaptcha-site-key"
RECAPTCHA_SECRET_KEY="your-recaptcha-secret-key"

# Maps Platform API Keys (obtained in previous steps)
PLACES_API_KEY="your-places-api-key"
MAPS_API_KEY="your-maps-api-key"

৬. কোডের সংক্ষিপ্ত বিবরণ

index.html

  • অ্যাপে টোকেন তৈরি করার জন্য ফায়ারবেস লাইব্রেরিগুলো লোড করে।
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Places API with AppCheck</title>
  <style></style>  </head>
<body>
  <div id="map"></div>

    <!-- Firebase services -->
  <script src="https://www.gstatic.com/firebasejs/9.15.0/firebase-app-compat.js"></script>
  <script src="https://www.gstatic.com/firebasejs/9.15.0/firebase-app-check-compat.js"></script>
  
  <script type="module" src="./script.js"></script> 
  <link rel="stylesheet" href="./style.css">
</body>
</html>

স্ক্রিপ্ট.জেএস

  • এপিআই কী সংগ্রহ করে: একটি ব্যাকএন্ড সার্ভার থেকে গুগল ম্যাপস এবং ফায়ারবেস অ্যাপ চেক-এর জন্য এপিআই কী সংগ্রহ করে।
  • ফায়ারবেস চালু করে: প্রমাণীকরণ এবং নিরাপত্তার জন্য ফায়ারবেস সেট আপ করে। (কনফিগারেশন প্রতিস্থাপন করুন → অধ্যায় ৪ দেখুন)।

ফায়ারবেস অ্যাপ চেক টোকেনের মেয়াদ ৩০ মিনিট থেকে ৭ দিন পর্যন্ত হয়ে থাকে এবং এটি ফায়ারবেস কনসোলে কনফিগার করা হয়। জোর করে টোকেন রিফ্রেশ করার চেষ্টা করেও এই মেয়াদ পরিবর্তন করা যায় না।

  • অ্যাপ চেক সক্রিয় করে: আগত অনুরোধের সত্যতা যাচাই করার জন্য ফায়ারবেস অ্যাপ চেক সক্ষম করে।
  • গুগল ম্যাপস এপিআই লোড করে: মানচিত্র প্রদর্শনের জন্য গুগল ম্যাপস জাভাস্ক্রিপ্ট লাইব্রেরিটি গতিশীলভাবে লোড করে।
  • ম্যাপ চালু করে: একটি ডিফল্ট অবস্থানকে কেন্দ্র করে একটি গুগল ম্যাপ তৈরি করে।
  • ম্যাপ ক্লিক পরিচালনা করে: ম্যাপে করা ক্লিক শোনে এবং সেই অনুযায়ী কেন্দ্রবিন্দু আপডেট করে।
  • প্লেসেস এপিআই কোয়েরি: ফায়ারবেস অ্যাপ ব্যবহার করে ক্লিক করা অবস্থানের কাছাকাছি স্থানগুলির (রেস্তোরাঁ, পার্ক, বার) তথ্য সংগ্রহের জন্য একটি ব্যাকএন্ড এপিআই-তে ( /api/data ) অনুরোধ পাঠায়। অনুমোদনের জন্য যাচাই করে।
  • মার্কার প্রদর্শন করে: সংগৃহীত ডেটাগুলোকে ম্যাপে মার্কার হিসেবে চিহ্নিত করে এবং সেগুলোর নাম ও আইকন দেখায়।
let mapsApiKey, recaptchaKey; // API keys
let currentAppCheckToken = null; // AppCheck token

async function init() {
  try {
    await fetchConfig(); // Load API keys from .env variable

    /////////// REPLACE with your Firebase configuration details
    const firebaseConfig = {
      apiKey: "AIza.......",
      authDomain: "places.......",
      projectId: "places.......",
      storageBucket: "places.......",
      messagingSenderId: "17.......",
      appId: "1:175.......",
      measurementId: "G-CPQ.......",
    };
    /////////// REPLACE 

    // Initialize Firebase and App Check
    await firebase.initializeApp(firebaseConfig);
    await firebase.appCheck().activate(recaptchaKey);

    // Get the initial App Check token
    currentAppCheckToken = await firebase.appCheck().getToken();

    // Load the Maps JavaScript API dynamically
    const scriptMaps = document.createElement("script");
    scriptMaps.src = `https://maps.googleapis.com/maps/api/js?key=${mapsApiKey}&libraries=marker,places&v=beta`;
    scriptMaps.async = true;
    scriptMaps.defer = true;
    scriptMaps.onload = initMap; // Create the map after the script loads
    document.head.appendChild(scriptMaps);
  } catch (error) {
    console.error("Firebase initialization error:", error);
    // Handle the error appropriately (e.g., display an error message)
  }
}
window.onload = init()

// Fetch configuration data from the backend API
async function fetchConfig() {
  const url = "/api/config";

  try {
    const response = await fetch(url);
    const config = await response.json();
    mapsApiKey = config.mapsApiKey;
    recaptchaKey = config.recaptchaKey;
  } catch (error) {
    console.error("Error fetching configuration:", error);
    // Handle the error (e.g., show a user-friendly message)
  }
}

// Initialize the map when the Maps API script loads
let map; // Dynamic Map
let center = { lat: 48.85557501, lng: 2.34565006 };
function initMap() {
  map = new google.maps.Map(document.getElementById("map"), {
    center: center,
    zoom: 13,
    mapId: "b93f5cef6674c1ff",
    zoomControlOptions: {
      position: google.maps.ControlPosition.RIGHT_TOP,
    },
    streetViewControl: false,
    mapTypeControl: false,
    clickableIcons: false,
    fullscreenControlOptions: {
      position: google.maps.ControlPosition.LEFT_TOP,
    },
  });

  // Initialize the info window for markers
  infoWindow = new google.maps.InfoWindow({});

  // Add a click listener to the map
  map.addListener("click", async (event) => {
    try {
      // Get a fresh App Check token on each click
      const appCheckToken = await firebase.appCheck().getToken();
      currentAppCheckToken = appCheckToken;

      // Update the center for the Places API query
      center.lat = event.latLng.lat();
      center.lng = event.latLng.lng();

      // Query for places with the new token and center
      queryPlaces();
    } catch (error) {
      console.error("Error getting App Check token:", error);
    }
  });
}

function queryPlaces() {
  const url = '/api/data'; // "http://localhost:3000/api/data"

  const body = {
    request: {
      includedTypes: ['restaurant', 'park', 'bar'],
      excludedTypes: [],
      maxResultCount: 20,
      locationRestriction: {
        circle: {
          center: {
            latitude: center.lat,
            longitude: center.lng,
          },
          radius: 4000,
        },
      },
    },
  };

  // Provides token to the backend using header: X-Firebase-AppCheck

  fetch(url, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'X-Firebase-AppCheck': currentAppCheckToken.token,
    },
    body: JSON.stringify(body),
  })
    .then((response) => response.json())
    .then((data) => {
      // display if response successful
      displayMarkers(data.places);
    })
    .catch((error) => {
      alert('No places');
      // eslint-disable-next-line no-console
      console.error('Error:', error);
    });
}


//// display places markers on map
...

সার্ভার.জেএস

  • একটি .env ফাইল থেকে এনভায়রনমেন্ট ভেরিয়েবল (এপিআই কী, গুগল প্রজেক্ট আইডি) লোড করে।
  • সার্ভারটি চালু হচ্ছে এবং http://localhost:3000 এ অনুরোধের জন্য অপেক্ষা করছে।
  • অ্যাপ্লিকেশন ডিফল্ট ক্রেডেনশিয়াল (ADC) ব্যবহার করে ফায়ারবেস অ্যাডমিন SDK চালু করে
  • script.js থেকে একটি reCAPTCHA টোকেন গ্রহণ করে
  • প্রাপ্ত টোকেনটির বৈধতা যাচাই করে।
  • টোকেনটি বৈধ হলে, অন্তর্ভুক্ত সার্চ প্যারামিটারসহ গুগল প্লেসেস এপিআই-তে একটি POST রিকোয়েস্ট পাঠানো হয়
  • Places API থেকে প্রাপ্ত প্রতিক্রিয়া প্রক্রিয়া করে ক্লায়েন্টের কাছে ফেরত পাঠায়
const express = require('express');
const axios = require('axios');

const admin = require('firebase-admin');

// .env variables
require('dotenv').config();

// Store sensitive API keys in environment variables
const recaptchaSite = process.env.RECAPTCHA_SITE_KEY;
const recaptchaSecret = process.env.RECAPTCHA_SECRET_KEY;
const placesApiKey = process.env.PLACES_API_KEY;
const mapsApiKey = process.env.MAPS_API_KEY;

// Verify environment variables loaded (only during development)
console.log('recaptchaSite:', recaptchaSite, '\n');
console.log('recaptchaSecret:', recaptchaSecret, '\n');

const app = express();
app.use(express.json());

// Firebase Admin SDK setup with Application Default Credentials (ADC)
const { GoogleAuth } = require('google-auth-library');
admin.initializeApp({
  // credential: admin.credential.applicationDefault(), // optional: explicit ADC
});

// Main API Endpoint 
app.post('/api/data', async (req, res) => {
  const appCheckToken = req.headers['x-firebase-appcheck'];

  console.log("\n", "Token", "\n", "\n", appCheckToken, "\n")

  try {
    // Verify Firebase App Check token for security
    const appCheckResult = await admin.appCheck().verifyToken(appCheckToken);

    if (appCheckResult.appId) {
      console.log('App Check verification successful!');
      placesQuery(req, res);
    } else {
      console.error('App Check verification failed.');
      res.status(403).json({ error: 'App Check verification failed.' });
    }
  } catch (error) {
    console.error('Error verifying App Check token:', error);
    res.status(500).json({ error: 'Error verifying App Check token.' });
  }
});

// Function to query Google Places API
async function placesQuery(req, res) {
  console.log('#################################');
  console.log('\n', 'placesApiKey:', placesApiKey, '\n');

  const queryObject = req.body.request;
  console.log('\n','Request','\n','\n', queryObject, '\n')

  const headers = {
    'Content-Type': 'application/json',
    'X-Goog-FieldMask': '*',
    'X-Goog-Api-Key': placesApiKey,
    'Referer': 'http://localhost:3000',  // Update for production(ie.: req.hostname)
  };

  const myUrl = 'https://places.googleapis.com/v1/places:searchNearby';

  try {
    // Authenticate with ADC
    const auth = new GoogleAuth();
    const { credential } = await auth.getApplicationDefault();

    const response = await axios.post(myUrl, queryObject, { headers, auth: credential });
    
    console.log('############### SUCCESS','\n','\n','Response','\n','\n', );
    const myBody = response.data;
    myBody.places.forEach(place => {
      console.log(place.displayName); 
    });
    res.json(myBody); // Use res.json for JSON data
  } catch (error) {
    console.log('############### ERROR');
    // console.error(error); // Log the detailed error for debugging
    res.status(error.response.status).json(error.response.data); // Use res.json for errors too
  }
}

// Configuration endpoint (send safe config data to the client)
app.get('/api/config', (req, res) => {
  res.json({
    mapsApiKey: process.env.MAPS_API_KEY, 
    recaptchaKey: process.env.RECAPTCHA_SITE_KEY, 
  });
});

// Serve static files
app.use(express.static('static'));

// Start the server
const port = process.env.PORT || 3000;
app.listen(port, () => {
  console.log(`Server listening on port ${port}`, '\n');
});

৭. অ্যাপ্লিকেশনটি চালান।

আপনার নির্বাচিত পরিবেশ থেকে টার্মিনালে সার্ভারটি চালু করুন এবং http://localhost:3000- এ যান।

npm start 

একটি টোকেন গ্লোবাল ভেরিয়েবল হিসেবে তৈরি করা হয়, যা ব্যবহারকারীর ব্রাউজার উইন্ডো থেকে গোপন রাখা হয় এবং প্রক্রিয়াকরণের জন্য সার্ভারে পাঠানো হয়। টোকেনটির বিস্তারিত তথ্য সার্ভার লগ-এ পাওয়া যাবে।

সার্ভারের কার্যকারিতা এবং প্লেসেস এপিআই নিয়ারবাই সার্চ অনুরোধের প্রতিক্রিয়া সম্পর্কিত বিস্তারিত তথ্য সার্ভার লগ-এ পাওয়া যাবে।

সমস্যা সমাধান:

সেটআপে গুগল প্রজেক্ট আইডি যেন সামঞ্জস্যপূর্ণ থাকে, তা নিশ্চিত করুন:

  • .env ফাইলে (GOOGLE_CLOUD_PROJECT ভেরিয়েবল)
  • টার্মিনালে gcloud কনফিগারেশন:
gcloud config set project your-project-id
  • reCaptcha সেটআপে

e6bddef9d5cf5460.png

  • ফায়ারবেস সেটআপে

7e17bfbcb8007763.png

অন্যান্য

  • একটি ডিবাগ টোকেন তৈরি করুন যা পরীক্ষা এবং সমস্যা সমাধানের উদ্দেশ্যে script.js এর মধ্যে reCAPTCHA সাইট কী-এর পরিবর্তে ব্যবহার করা যাবে।

9c0beb760d13faef.png

try {
 // Initialize Firebase first
 await firebase.initializeApp(firebaseConfig);
  // Set the debug token
  if (window.location.hostname === 'localhost') { // Only in development
    await firebase.appCheck().activate(
      'YOUR_DEBUG_FIREBASE_TOKEN', // Replace with the token from the console
      true // Set to true to indicate it's a debug token
      );
  } else {
      // Activate App Check
      await firebase.appCheck().activate(recaptchaKey);
}
  • বারবার অসফল প্রমাণীকরণের চেষ্টা, যেমন—ভুল রিক্যাপচা সাইট কী ব্যবহার করা, সাময়িকভাবে গতি হ্রাস (থ্রটলিং) ঘটাতে পারে।
FirebaseError: AppCheck: Requests throttled due to 403 error. Attempts allowed again after 01d:00m:00s (appCheck/throttled).

এডিসি ক্রেডেনশিয়াল

  • নিশ্চিত করুন যে আপনি সঠিক gcloud অ্যাকাউন্টে আছেন।
gcloud auth login 
  • প্রয়োজনীয় লাইব্রেরিগুলো ইনস্টল করা আছে কিনা তা নিশ্চিত করুন।
npm install @googlemaps/places firebase-admin
  • server.js- এ ফায়ারবেস লাইব্রেরি লোড করা আছে কিনা তা নিশ্চিত করুন।
const {GoogleAuth} = require('google-auth-library');
gcloud auth application-default login
  • ছদ্মবেশ ধারণ: ADC পরিচয়পত্র সংরক্ষিত আছে
gcloud auth application-default login --impersonate-service-account your_project@appspot.gserviceaccount.com
  • অবশেষে, স্থানীয়ভাবে ADC পরীক্ষা করার জন্য, নিম্নলিখিত স্ক্রিপ্টটি test.js নামে সংরক্ষণ করুন এবং টার্মিনালে চালান: node test.js
const {GoogleAuth} = require('google-auth-library');

async function requestTestADC() {
 try {
   // Authenticate using Application Default Credentials (ADC)
   const auth = new GoogleAuth();
   const {credential} = await auth.getApplicationDefault();

   // Check if the credential is successfully obtained
   if (credential) {
     console.log('Application Default Credentials (ADC) loaded successfully!');
     console.log('Credential:', credential); // Log the credential object
   } else {
     console.error('Error: Could not load Application Default Credentials (ADC).');
   }

   // ... rest of your code ...

 } catch (error) {
   console.error('Error:', error);
 }
}

requestTestADC();

৮. এই তো, খুব ভালো করেছো!

পরবর্তী পদক্ষেপ

অ্যাপ ইঞ্জিনে স্থাপন:

  • প্রয়োজনীয় কনফিগারেশন পরিবর্তনগুলো করে আপনার প্রজেক্টটি গুগল অ্যাপ ইঞ্জিনে ডেপ্লয়মেন্টের জন্য প্রস্তুত করুন।
  • আপনার অ্যাপ্লিকেশনটি ডেপ্লয় করতে gcloud কমান্ড-লাইন টুল অথবা অ্যাপ ইঞ্জিন কনসোল ব্যবহার করুন।

ফায়ারবেস প্রমাণীকরণ উন্নত করুন:

  • ডিফল্ট বনাম কাস্টম টোকেন: ফায়ারবেস পরিষেবাগুলির আরও গভীর ব্যবহারের জন্য ফায়ারবেস কাস্টম টোকেন প্রয়োগ করুন।
  • টোকেনের মেয়াদ: উপযুক্ত টোকেনের মেয়াদ নির্ধারণ করুন; সংবেদনশীল কার্যক্রমের জন্য স্বল্প মেয়াদ (কাস্টম ফায়ারবেস টোকেন, সর্বোচ্চ এক ঘণ্টা), এবং সাধারণ সেশনের জন্য দীর্ঘ মেয়াদ (reCAPTCHA টোকেন: ৩০ মিনিট থেকে ৭ ঘণ্টা)।
  • reCAPTCHA-এর বিকল্পগুলো খতিয়ে দেখুন: DeviceCheck (iOS), SafetyNet (Android), বা App Attest আপনার নিরাপত্তার প্রয়োজনের জন্য উপযুক্ত কিনা তা যাচাই করুন।

ফায়ারবেস পণ্যগুলি একীভূত করুন:

  • রিয়েলটাইম ডেটাবেস বা ফায়ারস্টোর: আপনার অ্যাপ্লিকেশনে যদি রিয়েল-টাইম ডেটা সিঙ্ক্রোনাইজেশন বা অফলাইন সক্ষমতার প্রয়োজন হয়, তবে রিয়েলটাইম ডেটাবেস বা ফায়ারস্টোরের সাথে ইন্টিগ্রেট করুন।
  • ক্লাউড স্টোরেজ: ছবি বা ভিডিওর মতো ব্যবহারকারী-সৃষ্ট কন্টেন্ট সংরক্ষণ ও পরিবেশনের জন্য ক্লাউড স্টোরেজ ব্যবহার করুন।
  • প্রমাণীকরণ: ব্যবহারকারী অ্যাকাউন্ট তৈরি করতে, লগইন সেশন পরিচালনা করতে এবং পাসওয়ার্ড রিসেট করতে ফায়ারবেস প্রমাণীকরণ ব্যবহার করুন।

মোবাইলে সম্প্রসারণ করুন:

  • অ্যান্ড্রয়েড এবং আইওএস: যদি আপনি একটি মোবাইল অ্যাপ তৈরি করার পরিকল্পনা করেন, তবে অ্যান্ড্রয়েড এবং আইওএস উভয় প্ল্যাটফর্মের জন্যই সংস্করণ তৈরি করুন।
  • ফায়ারবেস এসডিকে: আপনার মোবাইল অ্যাপে ফায়ারবেসের ফিচারগুলো নির্বিঘ্নে যুক্ত করতে অ্যান্ড্রয়েড এবং আইওএস-এর জন্য ফায়ারবেস এসডিকে ব্যবহার করুন।