التحقّق من صحة طلبات Places API باستخدام فحص التطبيقات من Firebase وReCAPTCHA

1. قبل البدء

لضمان شرعية المستخدمين الذين يتفاعلون مع تطبيق الويب، عليك تنفيذ ميزة "فحص التطبيقات من Firebase"، والاستفادة من رموز JWT المميزة في reCAPTCHA للتحقّق من صحة بيانات جلسات المستخدمين. سيسمح لك هذا الإعداد بمعالجة الطلبات الواردة من تطبيق العميل إلى Places API (الجديدة) بشكل آمن.

b40cfddb731786fa.png

Live Link

ما ستنشئه

لتوضيح ذلك، ستنشئ تطبيق ويب يعرض خريطة عند التحميل. سيتم أيضًا إنشاء رمز مميّز لخدمة reCAPTCHA بشكل غير ملحوظ باستخدام Firebase SDK. بعد ذلك، يتم إرسال الرمز المميّز إلى خادم Node.js، حيث تتحقّق منه Firebase قبل تلبية أي طلبات إلى Places API.

إذا كان الرمز المميّز صالحًا، سيخزّنه فحص التطبيقات من Firebase إلى أن تنتهي صلاحيته، ما يغنيك عن إنشاء رمز مميّز جديد لكل طلب من العميل. إذا كان الرمز المميّز غير صالح، سيُطلب من المستخدم إكمال اختبار التحقّق reCAPTCHA مرة أخرى للحصول على رمز مميّز جديد.

2. المتطلبات الأساسية

عليك التعرّف على العناصر أدناه لإكمال هذا الدرس التطبيقي. daea823b6bc38b67.png

منتجات Google Cloud المطلوبة

  • Google Cloud فحص التطبيقات من Firebase: قاعدة بيانات لإدارة الرموز المميزة
  • ‫Google reCAPTCHA: إنشاء الرموز المميزة والتحقّق منها وهي أداة تُستخدَم للتمييز بين المستخدمين وبرامج التتبُّع على المواقع الإلكترونية. تعمل هذه الميزة من خلال تحليل سلوك المستخدم وسمات المتصفّح ومعلومات الشبكة لإنشاء نتيجة تشير إلى احتمال أن يكون المستخدم برنامجًا آليًا. إذا كانت النتيجة مرتفعة بما يكفي، يُعدّ المستخدم بشريًا، ولا يلزم اتّخاذ أي إجراء آخر. إذا كانت النتيجة منخفضة، قد يتم عرض لغز CAPTCHA لتأكيد هوية المستخدم. هذا الأسلوب أقل تدخلاً من طرق CAPTCHA التقليدية، ما يجعل تجربة المستخدم أكثر سلاسة.
  • (اختياري) Google Cloud App Engine: بيئة النشر

منتجات "منصة خرائط Google" المطلوبة

في هذا الدرس التطبيقي حول الترميز، ستستخدم منتجات "منصة خرائط Google" التالية:

المتطلبات الأخرى لهذا الدرس التطبيقي حول الترميز

لإكمال هذا الدرس التطبيقي، ستحتاج إلى الحسابات والخدمات والأدوات التالية:

  • حساب على Google Cloud Platform تم تفعيل الفوترة فيه
  • مفتاح واجهة برمجة تطبيقات في "منصة خرائط Google" مع تفعيل Maps JavaScript API وPlaces
  • معرفة أساسية بلغات JavaScript وHTML وCSS
  • معرفة أساسية بلغة Node.js
  • محرّر نصوص أو بيئة تطوير متكاملة (IDE) من اختيارك

3- إكمال الإعداد

إعداد "منصة خرائط Google"

إذا لم يكن لديك حساب على Google Cloud Platform ومشروع مفعَّلة فيه الفوترة، يُرجى الاطّلاع على دليل البدء باستخدام "منصة خرائط Google" لإنشاء حساب فوترة ومشروع.

  1. في Cloud Console، انقر على القائمة المنسدلة الخاصة بالمشروع واختَر المشروع الذي تريد استخدامه في هذا الدرس العملي.

e7ffad81d93745cd.png

  1. فعِّل واجهات برمجة التطبيقات وحِزم تطوير البرامج (SDK) المطلوبة لهذا الدرس التطبيقي حول الترميز في Google Cloud Marketplace. لإجراء ذلك، اتّبِع الخطوات الواردة في هذا الفيديو أو هذه المستندات.
  2. أنشئ مفتاح واجهة برمجة تطبيقات في صفحة بيانات الاعتماد في Cloud Console. يمكنك اتّباع الخطوات الواردة في هذا الفيديو أو هذه المستندات. تتطلّب جميع الطلبات المُرسَلة إلى "منصة خرائط Google" مفتاح واجهة برمجة تطبيقات.

بيانات الاعتماد التلقائية للتطبيق

ستستخدِم مدير SDK في Firebase للتفاعل مع مشروع Firebase، بالإضافة إلى إرسال طلبات إلى Places API، وعليك تقديم بيانات اعتماد صالحة لكي تعمل.

سنستخدم مصادقة بيانات الاعتماد التلقائية لمصادقة خادمك من أجل إرسال الطلبات. بدلاً من ذلك (لا يُنصح بذلك)، يمكنك إنشاء حساب خدمة وتخزين بيانات الاعتماد في الرمز البرمجي.

التعريف: بيانات الاعتماد التلقائية للتطبيق (ADC) هي آلية توفّرها Google Cloud لمصادقة تطبيقاتك تلقائيًا بدون إدارة بيانات الاعتماد بشكلٍ صريح. يبحث عن بيانات الاعتماد في مواقع مختلفة (مثل متغيّرات البيئة أو ملفات حساب الخدمة أو خادم بيانات Google Cloud الوصفية) ويستخدم أول بيانات يعثر عليها.

  • في "نافذة الأوامر"، استخدِم الأمر التالي الذي يتيح لتطبيقاتك الوصول بأمان إلى موارد Google Cloud نيابةً عن المستخدم الذي سجّل الدخول حاليًا:
gcloud auth application-default login
  • ستنشئ ملف ‎ .env في الجذر يحدّد متغيّرًا لمشروع Google Cloud:
GOOGLE_CLOUD_PROJECT="your-project-id"

إنشاء حساب خدمة

  • علامة التبويب منصة خرائط Google > "+إنشاء بيانات اعتماد" > حساب الخدمة
  • أضِف دور "مشرف AppCheck" في Firebase، ثم أدخِل اسم حساب الخدمة الذي كتبته للتو، أي: firebase-appcheck-codelab@yourproject.iam.gserviceaccount.com

بيانات الاعتماد

  • انقر على حساب الخدمة الذي تم إنشاؤه.
  • انتقِل إلى علامة التبويب "المفاتيح" (KEYS) لإنشاء مفتاح > JSON > احفظ بيانات اعتماد JSON التي تم تنزيلها. انقل ملف xxx.json الذي تم تنزيله تلقائيًا إلى المجلد الجذر.
  • (الفصل التالي) أطلق عليه الاسم الصحيح في ملف nodejs server.js (​​firebase-credentials.json)

4. التكامل مع خدمة AppCheck من Firebase

ستحصل على تفاصيل إعداد Firebase ومفاتيح reCAPTCHA السرية.

عليك لصقها في التطبيق التجريبي وبدء الخادم.

إنشاء تطبيق في Firebase

اختَر مشروع Google Cloud الذي تم إنشاؤه من قبل (قد تحتاج إلى تحديد: "اختيار المورد الرئيسي").

a6d171c6d7e98087.png a16010ba102cc90b.png

  • إضافة تطبيق من "القائمة" (رمز الترس) في أعلى يمين الصفحة

18e5a7993ad9ea53.png 4632158304652118.png

رمز تهيئة Firebase

  • احفظ رمز تهيئة Firebase للصقه في script.js (الفصل التالي) من جهة العميل.

f10dcf6f5027e9f0.png

  • تسجيل تطبيقك للسماح لخدمة Firebase باستخدام رموز الإصدار الثالث من خدمة reCAPTCHA

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

da7efe203ce4142c.png

  • اختَر reCAPTCHA → إنشاء مفتاح في موقع reCAPTCHA الإلكتروني (مع ضبط النطاقات الصحيحة: localhost لتطوير التطبيقات)

b47eab131617467.png e6bddef9d5cf5460.png

  • لصق مفتاح reCAPTCHA السري في ميزة "فحص التطبيقات من Firebase"

a63bbd533a1b5437.png

  • يجب أن تتحوّل حالة التطبيق إلى اللون الأخضر

4f7962b527b78ee5.png

5- تطبيق تجريبي

  • تطبيق الويب الخاص بالعميل: ملفات HTML وJavaScript وCSS
  • الخادم: ملف Node.js
  • البيئة (.env): مفاتيح واجهة برمجة التطبيقات
  • الإعدادات (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

  • استرداد مفاتيح واجهة برمجة التطبيقات: يستردّ مفاتيح واجهة برمجة التطبيقات لخدمتَي "خرائط Google" و"فحص التطبيقات من Firebase" من خادم خلفي.
  • إعداد Firebase: يتم إعداد Firebase للمصادقة والأمان. (استبدال الإعدادات → راجِع الفصل 4).

يتم ضبط مدة صلاحية رمز مميّز لميزة "فحص التطبيقات من Firebase"، والتي تتراوح بين 30 دقيقة و7 أيام، ضِمن وحدة تحكّم Firebase ولا يمكن تغييرها من خلال محاولة فرض إعادة تحميل الرمز المميّز.

  • تفعيل ميزة "فحص التطبيقات": تتيح ميزة "فحص التطبيقات" من Firebase التحقّق من صحة الطلبات الواردة.
  • تحميل Google Maps API: يتم تحميل مكتبة JavaScript الخاصة بـ Google Maps بشكل ديناميكي لعرض الخريطة.
  • تهيئة الخريطة: يتم إنشاء خريطة Google في منتصف الموقع الجغرافي التلقائي.
  • التعامل مع النقرات على الخريطة: يستمع إلى النقرات على الخريطة ويعدّل نقطة مركزية وفقًا لذلك.
  • طلب البيانات من واجهة Places API: يتم إرسال طلبات إلى واجهة برمجة تطبيقات خلفية (/api/data) لاسترجاع معلومات حول الأماكن (المطاعم والحدائق والحانات) القريبة من الموقع الجغرافي الذي تم النقر عليه، وذلك باستخدام ميزة "فحص التطبيقات من Firebase" للحصول على إذن.
  • عرض العلامات: يرسم البيانات التي تم جلبها على الخريطة كعلامات، ويعرض أسماءها ورموزها.
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

  • تحميل متغيرات البيئة (مفاتيح واجهة برمجة التطبيقات ورقم تعريف مشروع Google) من ملف .env
  • يبدأ الخادم في الاستماع إلى الطلبات على http://localhost:3000.
  • تتم تهيئة مدير SDK في Firebase باستخدام بيانات الاعتماد التلقائية للتطبيق (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 في نافذة Terminal:
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 وشغِّله في Terminal: 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 المميّز المخصّص لمدة تصل إلى ساعة واحدة)، وأطول للجلسات العامة (رمز reCAPTCHA المميّز: من 30 دقيقة إلى 7 ساعات).
  • استكشاف بدائل reCAPTCHA: تحقَّق مما إذا كانت خدمات DeviceCheck (على أجهزة iOS) أو SafetyNet (على أجهزة Android) أو App Attest مناسبة لاحتياجاتك الأمنية.

دمج منتجات Firebase:

  • قاعدة بيانات الوقت الفعلي أو Firestore: إذا كان تطبيقك يحتاج إلى مزامنة البيانات في الوقت الفعلي أو إمكانات غير متصلة بالإنترنت، يمكنك الدمج مع قاعدة بيانات الوقت الفعلي أو Firestore.
  • Cloud Storage: يمكنك استخدام Cloud Storage لتخزين محتوى من إنشاء المستخدمين وعرضه، مثل الصور أو الفيديوهات.
  • المصادقة: يمكنك الاستفادة من خدمة مصادقة Firebase لإنشاء حسابات المستخدمين وإدارة جلسات تسجيل الدخول والتعامل مع عمليات إعادة ضبط كلمات المرور.

التوسّع ليشمل الأجهزة الجوّالة:

  • Android وiOS: إذا كنت تخطّط لإنشاء تطبيق على الأجهزة الجوّالة، عليك إنشاء إصدارات لكلّ من نظامَي التشغيل Android وiOS.
  • حِزم تطوير البرامج (SDK) لمنصة Firebase: استخدِم حِزم تطوير البرامج (SDK) لمنصة Firebase على نظامَي التشغيل Android وiOS لدمج ميزات Firebase بسلاسة في تطبيقاتك المتوافقة مع الأجهزة الجوّالة.