ตรวจสอบคำขอ Places API ด้วย Firebase AppCheck และ reCAPTCHA

1. ก่อนเริ่มต้น

คุณจะใช้ Firebase App Check เพื่อตรวจสอบความถูกต้องของผู้ใช้ที่โต้ตอบกับเว็บแอปพลิเคชัน โดยใช้ประโยชน์จากโทเค็น JWT ของ reCAPTCHA เพื่อยืนยันเซสชันของผู้ใช้ การตั้งค่านี้จะช่วยให้คุณจัดการคําขอจากแอปพลิเคชันไคลเอ็นต์ไปยัง Places API (ใหม่) ได้อย่างปลอดภัย

b40cfddb731786fa.png

ลิงก์แบบเรียลไทม์

สิ่งที่คุณจะสร้าง

ในการสาธิตนี้ คุณจะต้องสร้างเว็บแอปที่แสดงแผนที่เมื่อโหลด และจะสร้างโทเค็น reCAPTCHA โดยใช้ Firebase SDK อย่างรอบคอบ จากนั้นระบบจะส่งโทเค็นนี้ไปยังเซิร์ฟเวอร์ Node.js ซึ่ง Firebase จะตรวจสอบโทเค็นดังกล่าวก่อนที่จะดำเนินการตามคำขอไปยัง Places API

หากโทเค็นถูกต้อง Firebase App Check จะจัดเก็บโทเค็นไว้จนกว่าจะหมดอายุ ซึ่งจะช่วยลดความจำเป็นในการสร้างโทเค็นใหม่สำหรับคำขอไคลเอ็นต์ทุกรายการ หากโทเค็นไม่ถูกต้อง ระบบจะแจ้งให้ผู้ใช้ยืนยัน reCAPTCHA อีกครั้งเพื่อรับโทเค็นใหม่

2. ข้อกำหนดเบื้องต้น

คุณจะต้องทำความคุ้นเคยกับรายการด้านล่างเพื่อทํา Codelab นี้ให้เสร็จสมบูรณ์ daea823b6bc38b67.png

ผลิตภัณฑ์ Google Cloud ที่จําเป็น

  • Firebase App Check ของ Google Cloud: ฐานข้อมูลสําหรับการจัดการโทเค็น
  • Google reCAPTCHA: การสร้างและการยืนยันโทเค็น ซึ่งเป็นเครื่องมือที่ใช้แยกแยะมนุษย์ออกจากบ็อตในเว็บไซต์ โดยทำงานโดยวิเคราะห์พฤติกรรมของผู้ใช้ แอตทริบิวต์เบราว์เซอร์ และข้อมูลเครือข่ายเพื่อสร้างคะแนนที่บ่งบอกถึงความเป็นไปได้ที่ผู้ใช้จะเป็นบ็อต หากคะแนนสูงพอ ระบบจะถือว่าผู้ใช้เป็นมนุษย์และไม่จำเป็นต้องดำเนินการใดๆ เพิ่มเติม หากคะแนนต่ำ ระบบอาจแสดงภาพ CAPTCHA เพื่อยืนยันตัวตนของผู้ใช้ วิธีการนี้รบกวนผู้ใช้น้อยกว่าวิธีการ CAPTCHA แบบดั้งเดิม จึงช่วยให้ผู้ใช้ได้รับประสบการณ์การใช้งานที่ราบรื่นยิ่งขึ้น
  • (ไม่บังคับ) Google Cloud App Engine: สภาพแวดล้อมการทําให้ใช้งานได้

ผลิตภัณฑ์ Google Maps Platform ที่จําเป็น

ใน Codelab นี้ คุณจะใช้ผลิตภัณฑ์ Google Maps Platform ต่อไปนี้

ข้อกำหนดอื่นๆ สำหรับ Codelab นี้

คุณต้องมีบัญชี บริการ และเครื่องมือต่อไปนี้จึงจะทำ Codelab นี้ให้เสร็จสมบูรณ์ได้

  • บัญชี Google Cloud Platform ที่เปิดใช้การเรียกเก็บเงิน
  • คีย์ API ของ Google Maps Platform ที่เปิดใช้ Maps JavaScript API และ Places
  • ความรู้พื้นฐานเกี่ยวกับ JavaScript, HTML และ CSS
  • ความรู้พื้นฐานเกี่ยวกับ Node.js
  • เครื่องมือแก้ไขข้อความหรือ IDE ที่คุณเลือก

3. เตรียมตัว

ตั้งค่า Google Maps Platform

หากคุณยังไม่มีบัญชี Google Cloud Platform และโปรเจ็กต์ที่เปิดใช้การเรียกเก็บเงิน โปรดดูคู่มือเริ่มต้นใช้งาน Google Maps Platform เพื่อสร้างบัญชีการเรียกเก็บเงินและโปรเจ็กต์

  1. ใน Cloud Console ให้คลิกเมนูแบบเลื่อนลงของโปรเจ็กต์ แล้วเลือกโปรเจ็กต์ที่ต้องการใช้สำหรับโค้ดแล็บนี้

e7ffad81d93745cd.png

  1. เปิดใช้ Google Maps Platform API และ SDK ที่จําเป็นสําหรับโค้ดแล็บนี้ใน Google Cloud Marketplace โดยทำตามขั้นตอนในวิดีโอนี้หรือเอกสารประกอบนี้
  2. สร้างคีย์ API ในหน้าข้อมูลเข้าสู่ระบบของ Cloud Console คุณสามารถทำตามขั้นตอนในวิดีโอนี้หรือเอกสารประกอบนี้ คำขอทั้งหมดที่ส่งไปยัง Google Maps Platform ต้องใช้คีย์ API

ข้อมูลเข้าสู่ระบบเริ่มต้นของแอปพลิเคชัน

คุณจะใช้ Firebase Admin SDK เพื่อโต้ตอบกับโปรเจ็กต์ Firebase รวมถึงส่งคําขอไปยัง Places API และจะต้องระบุข้อมูลเข้าสู่ระบบที่ถูกต้องเพื่อให้ใช้งานได้

เราจะใช้การตรวจสอบสิทธิ์ ADC (ข้อมูลเข้าสู่ระบบเริ่มต้นอัตโนมัติ) เพื่อตรวจสอบสิทธิ์เซิร์ฟเวอร์ของคุณในการส่งคำขอ หรือ (ไม่แนะนำ) คุณอาจสร้างบัญชีบริการและจัดเก็บข้อมูลเข้าสู่ระบบไว้ในโค้ดก็ได้

คําจํากัดความ: ข้อมูลเข้าสู่ระบบเริ่มต้นของแอปพลิเคชัน (ADC) คือกลไกที่ Google Cloud มีไว้เพื่อตรวจสอบสิทธิ์แอปพลิเคชันโดยอัตโนมัติโดยไม่ต้องจัดการข้อมูลเข้าสู่ระบบอย่างชัดเจน โดยจะค้นหาข้อมูลเข้าสู่ระบบในตำแหน่งต่างๆ (เช่น ตัวแปรสภาพแวดล้อม ไฟล์บัญชีบริการ หรือเซิร์ฟเวอร์ข้อมูลเมตาของ Google Cloud) และใช้ข้อมูลเข้าสู่ระบบรายการแรกที่พบ

  • ในเทอร์มินัล ให้ใช้คําสั่งด้านล่างที่อนุญาตให้แอปพลิเคชันเข้าถึงทรัพยากร Google Cloud อย่างปลอดภัยในนามของผู้ใช้ที่เข้าสู่ระบบอยู่ในขณะนี้
gcloud auth application-default login
  • คุณจะต้องสร้างไฟล์ .env ที่รูทซึ่งระบุตัวแปรโปรเจ็กต์ Google Cloud ดังนี้
GOOGLE_CLOUD_PROJECT="your-project-id"

สร้างบัญชีบริการ

  • แท็บ Google Maps Platform > "+สร้างข้อมูลเข้าสู่ระบบ" > บัญชีบริการ
  • เพิ่มบทบาทผู้ดูแลระบบ Firebase AppCheck แล้วป้อนชื่อบัญชีบริการที่คุณเพิ่งพิมพ์ เช่น firebase-appcheck-codelab@yourproject.iam.gserviceaccount.com

ข้อมูลเข้าสู่ระบบ

  • คลิกบัญชีบริการที่สร้าง
  • ไปที่แท็บ "คีย์" เพื่อสร้างคีย์ > JSON > บันทึกข้อมูลเข้าสู่ระบบ JSON ที่ดาวน์โหลด ย้ายไฟล์ xxx.json ที่ดาวน์โหลดโดยอัตโนมัติไปยังโฟลเดอร์รูท
  • (บทถัดไป) ตั้งชื่อให้ถูกต้องในไฟล์ nodejs server.js (firebase-credentials.json)

4. การผสานรวม Firebase AppCheck

คุณจะได้รับรายละเอียดการกําหนดค่า Firebase และคีย์ข้อมูลลับ reCAPTCHA

คุณจะวางลงในแอปพลิเคชันเดโมและเริ่มเซิร์ฟเวอร์

สร้างแอปพลิเคชันใน Firebase

เลือกโปรเจ็กต์ Google Cloud ที่สร้างไว้แล้ว (คุณอาจต้องระบุ "การเลือกทรัพยากรหลัก")"

a6d171c6d7e98087.png a16010ba102cc90b.png

  • เพิ่มแอปพลิเคชันจากเมนูด้านซ้ายบน (รูปเฟือง)

18e5a7993ad9ea53.png 4632158304652118.png

โค้ดเริ่มต้น Firebase

  • บันทึกโค้ดเริ่มต้น Firebase เพื่อวางใน script.js (บทถัดไป) สำหรับฝั่งไคลเอ็นต์

f10dcf6f5027e9f0.png

  • ลงทะเบียนแอปเพื่ออนุญาตให้ Firebase ใช้โทเค็น reCAPTCHA v3

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

da7efe203ce4142c.png

  • เลือก reCAPTCHA → สร้างคีย์ในเว็บไซต์ reCAPTCHA (กำหนดค่าโดเมนที่ถูกต้อง: localhost สําหรับนักพัฒนาแอป)

b47eab131617467.png e6bddef9d5cf5460.png

  • วางคีย์ลับ reCAPTCHA ใน Firebase AppCheck

a63bbd533a1b5437.png

  • สถานะแอปควรเปลี่ยนเป็นสีเขียว

4f7962b527b78ee5.png

5. แอปพลิเคชันสาธิต

  • เว็บแอปไคลเอ็นต์: ไฟล์ HTML, JavaScript, CSS
  • เซิร์ฟเวอร์: ไฟล์ Node.js
  • สภาพแวดล้อม (.env): คีย์ API
  • การกําหนดค่า (app.yaml): การตั้งค่าการติดตั้งใช้งาน Google App Engine

การตั้งค่า Node.js

  • ไปยังส่วนต่างๆ: เปิดเทอร์มินัลแล้วไปที่ไดเรกทอรีรากของโปรเจ็กต์ที่โคลน
  • ติดตั้ง Node.js (หากจำเป็น): เวอร์ชัน 18 ขึ้นไป
node -v  # Check installed version
  • เริ่มต้นโปรเจ็กต์: เรียกใช้คำสั่งต่อไปนี้เพื่อเริ่มต้นโปรเจ็กต์ Node.js ใหม่โดยให้การตั้งค่าทั้งหมดเป็นค่าเริ่มต้น
npm init 
  • ติดตั้งการอ้างอิง: ใช้คำสั่งต่อไปนี้เพื่อติดตั้งการอ้างอิงที่จำเป็นของโปรเจ็กต์
npm install @googlemaps/places firebase-admin express axios dotenv

การกําหนดค่า: ตัวแปรสภาพแวดล้อมสําหรับโปรเจ็กต์ Google Cloud

  • การสร้างไฟล์สภาพแวดล้อม: สร้างไฟล์ชื่อ .env ในไดเรกทอรีรูทของโปรเจ็กต์ ไฟล์นี้จะจัดเก็บข้อมูลการกําหนดค่าที่ละเอียดอ่อนและไม่ควรทําการคอมมิตกับระบบควบคุมเวอร์ชัน
  • ป้อนข้อมูลตัวแปรสภาพแวดล้อม: เปิดไฟล์ .env แล้วเพิ่มตัวแปรต่อไปนี้ โดยแทนที่ตัวยึดตําแหน่งด้วยค่าจริงจากโปรเจ็กต์ Google Cloud
# 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"

6. ภาพรวมโค้ด

index.html

  • โหลดไลบรารี Firebase เพื่อสร้างโทเค็นในแอป
<!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>

script.js

  • ดึงข้อมูลคีย์ API: ดึงข้อมูลคีย์ API สําหรับ Google Maps และ Firebase App Check จากเซิร์ฟเวอร์แบ็กเอนด์
  • เริ่มต้น Firebase: ตั้งค่า Firebase สําหรับการตรวจสอบสิทธิ์และความปลอดภัย (แทนที่การกําหนดค่า → ดูบทที่ 4)

ระยะเวลาที่โทเค็น Firebase App Check ใช้งานได้มีตั้งแต่ 30 นาทีถึง 7 วัน โดยกำหนดค่าไว้ในคอนโซล Firebase และไม่สามารถเปลี่ยนแปลงได้ด้วยการพยายามบังคับให้รีเฟรชโทเค็น

  • เปิดใช้งาน App Check: เปิดใช้ Firebase App Check เพื่อยืนยันความถูกต้องของคําขอขาเข้า
  • โหลด Google Maps API: โหลดไลบรารี JavaScript ของ Google Maps แบบไดนามิกเพื่อแสดงแผนที่
  • เริ่มต้นแผนที่: สร้าง Google Maps ที่กําหนดศูนย์กลางเป็นตําแหน่งเริ่มต้น
  • จัดการการคลิกแผนที่: คอยฟังการคลิกบนแผนที่และอัปเดตจุดศูนย์กลางตามความเหมาะสม
  • ค้นหา Places API: ส่งคําขอไปยังแบ็กเอนด์ API (/api/data) เพื่อดึงข้อมูลเกี่ยวกับสถานที่ (ร้านอาหาร สวนสาธารณะ บาร์) ที่อยู่ใกล้กับตําแหน่งที่คลิก โดยใช้ Firebase App Check ในการให้สิทธิ์
  • แสดงเครื่องหมาย: แสดงข้อมูลที่ดึงข้อมูลบนแผนที่เป็นเครื่องหมาย พร้อมแสดงชื่อและไอคอน
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
...

server.js

  • โหลดตัวแปรสภาพแวดล้อม (คีย์ API, รหัสโปรเจ็กต์ Google) จากไฟล์ .env
  • เริ่มเซิร์ฟเวอร์เพื่อรอรับคำขอใน http://localhost:3000
  • เริ่มต้น Firebase Admin SDK โดยใช้ข้อมูลเข้าสู่ระบบเริ่มต้นของแอปพลิเคชัน (ADC)
  • ได้รับโทเค็น reCAPTCHA จาก script.js
  • ยืนยันความถูกต้องของโทเค็นที่ได้รับ
  • หากโทเค็นถูกต้อง ระบบจะส่งคําขอ POST ไปยัง Google Places API พร้อมพารามิเตอร์การค้นหาที่รวมอยู่ด้วย
  • ประมวลผลและแสดงผลลัพธ์จาก 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');
});

7. เรียกใช้แอปพลิเคชัน

จากสภาพแวดล้อมที่เลือก ให้เรียกใช้เซิร์ฟเวอร์จากเทอร์มินัลและไปที่ http://localhost:3000

npm start 

ระบบจะสร้างโทเค็นเป็นตัวแปรส่วนกลาง ซ่อนจากหน้าต่างเบราว์เซอร์ของผู้ใช้ และส่งไปยังเซิร์ฟเวอร์เพื่อประมวลผล ดูรายละเอียดของโทเค็นได้ในบันทึกของเซิร์ฟเวอร์

รายละเอียดเกี่ยวกับฟังก์ชันของเซิร์ฟเวอร์และการตอบสนองต่อคำขอการค้นหาใกล้เคียงของ Places API อยู่ในบันทึกของเซิร์ฟเวอร์

การแก้ปัญหา:

ตรวจสอบว่ารหัสโปรเจ็กต์ Google ที่สอดคล้องกันในการตั้งค่า

  • ในไฟล์ .env (ตัวแปร GOOGLE_CLOUD_PROJECT)
  • ในการกำหนดค่า gcloud ของเทอร์มินัล ให้ทำดังนี้
gcloud config set project your-project-id
  • ในการตั้งค่า reCAPTCHA

e6bddef9d5cf5460.png

  • ในการตั้งค่า Firebase

7e17bfbcb8007763.png

อื่นๆ

  • สร้างโทเค็นแก้ไขข้อบกพร่องที่ใช้แทนคีย์ของเว็บไซต์ reCAPTCHA ได้ภายใน script.js เพื่อวัตถุประสงค์ในการทดสอบและการแก้ปัญหา

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);
}
  • การพยายามตรวจสอบสิทธิ์ไม่สำเร็จหลายครั้งเกินไป เช่น การใช้คีย์เว็บไซต์ ReCaptcha ที่ไม่ถูกต้อง อาจทริกเกอร์การจำกัดชั่วคราว
FirebaseError: AppCheck: Requests throttled due to 403 error. Attempts allowed again after 01d:00m:00s (appCheck/throttled).

ข้อมูลเข้าสู่ระบบ ADC

  • ตรวจสอบว่าคุณใช้บัญชี gcloud ที่ถูกต้อง
gcloud auth login 
  • ตรวจสอบว่าติดตั้งไลบรารีที่จำเป็นแล้ว
npm install @googlemaps/places firebase-admin
  • ตรวจสอบว่าโหลดไลบรารี Firebase ใน 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();

8. เยี่ยมไปเลย

ขั้นตอนติดตามผล

การทำให้ใช้งานได้กับ App Engine:

  • เตรียมโปรเจ็กต์ให้พร้อมสำหรับการติดตั้งใช้งานใน Google App Engine โดยทำการเปลี่ยนแปลงการกำหนดค่าที่จำเป็น
  • ใช้gcloudเครื่องมือบรรทัดคำสั่งหรือคอนโซล App Engine เพื่อทำให้แอปพลิเคชันใช้งานได้

เพิ่มประสิทธิภาพการตรวจสอบสิทธิ์ Firebase:

  • โทเค็นเริ่มต้นกับโทเค็นที่กำหนดเอง: ใช้โทเค็นที่กำหนดเองของ Firebase เพื่อใช้บริการ Firebase ได้อย่างละเอียดยิ่งขึ้น
  • อายุการใช้งานของโทเค็น: ตั้งค่าอายุการใช้งานของโทเค็นที่เหมาะสม โดยให้สั้นลงสําหรับการดำเนินการที่มีความละเอียดอ่อน (โทเค็น Firebase ที่กําหนดเองสูงสุด 1 ชั่วโมง) และนานขึ้นสําหรับเซสชันทั่วไป (โทเค็น reCAPTCHA: 30 นาทีถึง 7 ชั่วโมง)
  • สำรวจทางเลือกอื่นๆ นอกเหนือจาก reCAPTCHA: ตรวจสอบว่า DeviceCheck (iOS), SafetyNet (Android) หรือ App Attest เหมาะกับความต้องการด้านความปลอดภัยของคุณหรือไม่

ผสานรวมผลิตภัณฑ์ Firebase:

  • Realtime Database หรือ Firestore: หากแอปพลิเคชันต้องการการซิงค์ข้อมูลแบบเรียลไทม์หรือความสามารถในการทำงานแบบออฟไลน์ ให้ผสานรวมกับ Realtime Database หรือ Firestore
  • พื้นที่เก็บข้อมูลระบบคลาวด์: ใช้พื้นที่เก็บข้อมูลระบบคลาวด์สำหรับจัดเก็บและแสดงเนื้อหาที่ผู้ใช้สร้างขึ้น เช่น รูปภาพหรือวิดีโอ
  • การตรวจสอบสิทธิ์: ใช้ประโยชน์จากการตรวจสอบสิทธิ์ Firebase เพื่อสร้างบัญชีผู้ใช้ จัดการเซสชันการเข้าสู่ระบบ และจัดการการรีเซ็ตรหัสผ่าน

ขยายไปยังอุปกรณ์เคลื่อนที่:

  • Android และ iOS: หากวางแผนที่จะมีแอปบนอุปกรณ์เคลื่อนที่ ให้สร้างเวอร์ชันสำหรับทั้งแพลตฟอร์ม Android และ iOS
  • Firebase SDK: ใช้ Firebase SDK สําหรับ Android และ iOS เพื่อผสานรวมฟีเจอร์ Firebase เข้ากับแอปบนอุปกรณ์เคลื่อนที่ได้อย่างราบรื่น