1- قبل البدء
تنفِّذ إضافة Firebase مهمة محدّدة أو مجموعة من المهام استجابةً لطلبات HTTP أو بدء الأحداث من منتجات Firebase وGoogle الأخرى، مثل خدمة المراسلة عبر السحابة الإلكترونية من Firebase أو Cloud Firestore أو Pub/Sub.
ما الذي ستنشئه
في هذا الدرس التطبيقي حول الترميز، ستنشئ إضافة Firebase بهدف التجزئة الجغرافية. بعد نشر الإضافة، تحوِّل الإحداثي السيني (X) والإحداثي الصادي (Y) إلى تجزئة جغرافية استجابةً لأحداث Firestore أو من خلال استدعاء الدوال القابلة للاستدعاء. يمكن استخدام ذلك كبديل لتنفيذ مكتبة الأجهزة الجغرافية على جميع الأنظمة الأساسية المستهدفة لتخزين البيانات، ما يوفر لك الوقت.
المعلومات التي ستطّلع عليها
- كيفية استخدام رمز وظائف السحابة الإلكترونية الحالي وتحويله إلى إضافة Firebase قابلة للتوزيع
- كيفية إعداد ملف
extension.yaml
- كيفية تخزين السلاسل الحساسة (مفاتيح واجهة برمجة التطبيقات) في إحدى الإضافات
- كيفية السماح لمطوّري الإضافة بضبطها بما يتناسب مع احتياجاتهم
- كيفية اختبار الإضافة ونشرها
المتطلبات
- واجهة سطر الأوامر في Firebase (التثبيت وتسجيل الدخول)
- حساب Google، مثل حساب Gmail
- Node.js و
npm
- بيئة التطوير المفضلة لديك
2- البدء في الإعداد
الحصول على الرمز
كل ما تحتاجه لهذه الإضافة متوفر في مستودع GitHub. للبدء، احصل على الرمز وافتحه في بيئة التطوير المفضَّلة لديك.
- فك ضغط ملف ZIP الذي تم تنزيله.
- لتثبيت الملحقات المطلوبة، افتح الوحدة الطرفية في دليل
functions
وشغِّل الأمرnpm install
.
إعداد Firebase
يشجّع هذا الدرس التطبيقي حول الترميز بشدة على استخدام أدوات محاكاة Firebase. إذا كنت تريد تجربة تطوير الإضافات باستخدام مشروع حقيقي في Firebase، اطّلِع على المقالة إنشاء مشروع على Firebase. يستخدم هذا الدرس التطبيقي حول الترميز دوال Cloud، لذا إذا كنت تستخدم مشروع Firebase حقيقيًا بدلاً من المحاكيات، عليك الترقية إلى خطة أسعار Blaze.
هل تريد التخطّي إلى العنصر التالي؟
يمكنك تنزيل نسخة مكتملة من الدرس التطبيقي حول الترميز. إذا واجهتك مشكلة أثناء ذلك أو إذا أردت معرفة الشكل الذي تظهر به الإضافة المكتملة، يمكنك الاطّلاع على فرع codelab-end
من مستودع GitHub أو تنزيل ملف ZIP المكتمل.
3- مراجعة الرمز البرمجي
- افتح ملف
index.ts
من ملف ZIP. لاحِظ أنّها تحتوي على إعلانَي دالات في السحابة الإلكترونية داخلها.
ما هي وظيفة هذه الدوال؟
تُستخدم الدوال التجريبية هذه للتجزئة الجغرافية. تأخذ زوجًا من الإحداثيات وتحولها إلى تنسيق محسّن للاستعلامات الجغرافية في Firestore. تحاكي الدوال استخدام طلب بيانات من واجهة برمجة التطبيقات حتى تتمكّن من معرفة المزيد من المعلومات حول التعامل مع أنواع البيانات الحسّاسة في الإضافات. لمزيد من المعلومات، يمكنك الاطّلاع على المستندات حول إجراء طلبات بحث عن الموقع الجغرافي بشأن البيانات في Firestore.
ثوابت الدوال
يتم الإعلان عن الثوابت في وقت مبكر، في أعلى ملف index.ts
. تتم الإشارة إلى بعض هذه الثوابت في عوامل التشغيل المحدّدة للإضافة.
index.ts
import {firestore} from "firebase-functions";
import {initializeApp} from "firebase-admin/app";
import {GeoHashService, ResultStatusCode} from "./fake-geohash-service";
import {onCall} from "firebase-functions/v1/https";
import {fieldValueExists} from "./utils";
const documentPath = "users/{uid}";
const xField = "xv";
const yField = "yv";
const apiKey = "1234567890";
const outputField = "hash";
initializeApp();
const service = new GeoHashService(apiKey);
عامل تشغيل Firestore
تظهر الدالة الأولى في ملف index.ts
على النحو التالي:
index.ts
export const locationUpdate = firestore.document(documentPath)
.onWrite((change) => {
// item deleted
if (change.after == null) {
return 0;
}
// double check that both values exist for computation
if (
!fieldValueExists(change.after.data(), xField) ||
!fieldValueExists(change.after.data(), yField)
) {
return 0;
}
const x: number = change.after.data()![xField];
const y: number = change.after.data()![yField];
const hash = service.convertToHash(x, y);
// This is to check whether the hash value has changed. If
// it hasn't, you don't want to write to the document again as it
// would create a recursive write loop.
if (fieldValueExists(change.after.data(), outputField)
&& change.after.data()![outputField] == hash) {
return 0;
}
return change.after.ref
.update(
{
[outputField]: hash.hash,
}
);
});
هذه الدالة هي مشغِّل Firestore. عند وقوع حدث كتابة في قاعدة البيانات، تتفاعل الدالة مع هذا الحدث من خلال البحث عن حقل xv
والحقل yv
. وفي حال توفُّر هذين الحقلَين، ستحسب التجزئة الجغرافية وتكتب الناتج في موقع محدّد لإخراج المستند. يتم تحديد مستند الإدخال من خلال الثابت users/{uid}
، ما يعني أنّ الدالة تقرأ كل مستند مكتوب في مجموعة users/
، ثم تعالج تجزئة جغرافية لهذه المستندات. ثم تُخرج التجزئة في حقل تجزئة في المستند نفسه.
الوظائف القابلة للاستدعاء
تظهر الدالة التالية في ملف index.ts
على النحو التالي:
موقع index.ts
export const callableHash = onCall((data, context) => {
if (context.auth == undefined) {
return {error: "Only authorized users are allowed to call this endpoint"};
}
const x = data[xField];
const y = data[yField];
if (x == undefined || y == undefined) {
return {error: "Either x or y parameter was not declared"};
}
const result = service.convertToHash(x, y);
if (result.status != ResultStatusCode.ok) {
return {error: `Something went wrong ${result.message}`};
}
return {result: result.hash};
});
لاحِظ الدالة onCall
. ويشير إلى أن هذه الدالة هي دالة قابلة للاستدعاء، والتي يمكن استدعاؤها من داخل رمز تطبيق العميل. تستخدم هذه الدالة القابلة للاستدعاء المعلمتَين x
وy
وتعرض تجزئة جغرافية. على الرغم من أنّه لن يتم استدعاء هذه الدالة مباشرةً في هذا الدرس التطبيقي حول الترميز، يتم تضمينها هنا كمثال على عنصر يجب ضبطه في إضافة Firebase.
4. إعداد ملف extension.yaml
والآن بعد أن عرفت ما الذي يؤديه رمز دوال Cloud في إضافتك، أصبحت جاهزًا لتجميعه للتوزيع. تأتي كل إضافة من إضافات Firebase مزودة بملف extension.yaml
يصف وظيفة الإضافة وآلية عملها.
يتطلب ملف extension.yaml
بعض البيانات الوصفية الأولية حول إضافتك. تساعدك كل خطوة من الخطوات التالية في فهم معنى جميع الحقول وسبب حاجتك إليها.
- أنشئ ملف
extension.yaml
في الدليل الجذري للمشروع الذي نزّلته سابقًا. ابدأ بإضافة ما يلي:
name: geohash-ext
version: 0.0.1
specVersion: v1beta # Firebase Extensions specification version (do not edit)
يُستخدَم اسم الإضافة كقاعدة لرقم تعريف المثيل للإضافة (يمكن للمستخدمين تثبيت مثيلات متعددة للإضافة، ولكل منها رقم تعريف خاص بها). بعد ذلك، ينشئ Firebase اسم حسابات خدمة الإضافة والموارد المتعلقة بالإضافة باستخدام رقم تعريف هذا المثيل. يشير رقم الإصدار إلى إصدار الإضافة. ويجب أن تتبع هذه الطريقة تحديد الإصدارات الدلالية، وعليك تعديلها كلما أجريت تغييرات على وظائف الإضافة. ويُستخدم إصدار مواصفات الإضافة لتحديد مواصفات إضافات Firebase المطلوب اتباعها، وفي هذه الحالة، سيتم استخدام v1beta
.
- أضف بعض التفاصيل سهلة الاستخدام إلى ملف YAML:
...
displayName: Latitude and longitude to GeoHash converter
description: A converter for changing your Latitude and longitude coordinates to geohashes.
الاسم المعروض هو تمثيل سهل لاسم إضافتك عندما يتفاعل المطورون مع إضافتك. يقدّم الوصف نظرة عامة مختصرة حول وظيفة الإضافة. عند نشر الإضافة على extensions.dev، ستظهر على النحو التالي:
- حدِّد ترخيص الرمز في الإضافة.
...
license: Apache-2.0 # The license you want for the extension
- حدد الشخص الذي كتب الإضافة وما إذا كانت الفوترة مطلوبة لتثبيتها أم لا:
...
author:
authorName: AUTHOR_NAME
url: https://github.com/Firebase
billingRequired: true
يُستخدم القسم author
للسماح للمستخدمين بمعرفة الجهة التي يجب التواصل معها في حال مواجهتهم مشاكل في الإضافة أو أرادوا الحصول على مزيد من المعلومات عنها. billingRequired
هي مَعلمة مطلوبة ويجب ضبطها على true
لأنّ جميع الإضافات تعتمد على دوال Cloud، والتي تتطلّب خطة Blaze.
ويغطي هذا الحد الأدنى من عدد الحقول المطلوبة في ملف extension.yaml
لتحديد هذه الإضافة. ولمزيد من التفاصيل عن معلومات التعريف الأخرى التي يمكنك تحديدها في إحدى الإضافات، يُرجى الاطّلاع على المستندات.
5- تحويل رمز دوال السحابة إلى مورد للإضافات
مورد الإضافة هو عنصر ينشئه Firebase في المشروع أثناء تثبيت إحدى الإضافات. تمتلك الإضافة بعد ذلك هذه الموارد ولديها حساب خدمة محدد يعمل عليها. في هذا المشروع، تكون هذه الموارد هي Cloud Functions، ويجب تحديدها في ملف extension.yaml
لأنّ الإضافة لن تنشئ موارد تلقائيًا من الرمز البرمجي في مجلد الدوال. إذا لم يتم تعريف دوال السحابة الإلكترونية صراحةً كمورد، لا يمكن نشرها عند نشر الإضافة.
موقع النشر الذي حدّده المستخدم
- يمكنك السماح للمستخدم بتحديد الموقع الجغرافي الذي يريد نشر هذه الإضافة فيه وتحديد ما إذا كان من الأفضل استضافة الإضافة بالقرب من المستخدمين النهائيين أو بالقرب من قاعدة البيانات. في ملف
extension.yaml
، يجب تضمين خيار اختيار موقع جغرافي.
extension.yaml
أنت الآن جاهز لكتابة الإعدادات لمورد الدالة.
- في الملف
extension.yaml
، أنشِئ كائن مورد للدالةlocationUpdate
. إلحاق ما يلي بملفextension.yaml
:
resources:
- name: locationUpdate
type: firebaseextensions.v1beta.function
properties:
eventTrigger:
eventType: providers/cloud.firestore/eventTypes/document.write
resource: projects/${PROJECT_ID}/databases/(default)/documents/users/{uid}
يمكنك تعريف name
على أنّه اسم الدالة المحدّد في ملف index.ts
الخاص بالمشروع. يمكنك تحديد type
للدالة التي يتم نشرها، والتي يجب أن تكون دائمًا firebaseextensions.v1beta.function
، في الوقت الحالي. بعد ذلك، يمكنك تحديد properties
لهذه الدالة. إنّ السمة الأولى التي تحدّدها هي eventTrigger
المرتبطة بهذه الدالة. لإجراء نسخ مطابق للميزات التي تتيحها الإضافة حاليًا، يمكنك استخدام eventType
من providers/cloud.firestore/eventTypes/document.write
، والموجودة في مستندات كتابة دوال السحابة الإلكترونية للإضافة. يمكنك تحديد resource
على أنّه الموقع الجغرافي للمستندات. بما أنّ هدفك الحالي هو عكس محتوى الرمز البرمجي، يستمع مسار المستند إلى users/{uid}
، مع تحديد الموقع التلقائي لقاعدة البيانات الذي يسبقه.
- تحتاج الإضافة إلى أذونات القراءة والكتابة لقاعدة بيانات Firestore. في نهاية ملف
extension.yaml
، حدِّد أدوار "إدارة الهوية وإمكانية الوصول" التي يجب أن تتمكّن الإضافة من الوصول إليها من أجل العمل مع قاعدة البيانات في مشروع Firebase للمطوّر.
roles:
- role: datastore.user
reason: Allows the extension to read / write to your Firestore instance.
يأتي الدور "datastore.user
" من قائمة أدوار "إدارة الهوية وإمكانية الوصول" المتاحة للإضافات. وبما أنّ الإضافة ستكون للقراءة والكتابة، فإن دور "datastore.user
" يتناسب تمامًا مع هذه الإضافة.
- يجب أيضًا إضافة الدالة القابلة للاستدعاء. في الملف
extension.yaml
، أنشِئ موردًا جديدًا ضمن السمة "الموارد". هذه السمات خاصة بدالّة قابلة للاستدعاء:
- name: callableHash
type: firebaseextensions.v1beta.function
properties:
httpsTrigger: {}
ومع أنّ المورد السابق استخدم eventTrigger
، يمكنك استخدام httpsTrigger
هنا، وهو يشمل الدوال القابلة للاستدعاء ووظائف HTTPS.
التحقّق من الرموز
كان هذا الكثير من الإعدادات لجعل extension.yaml
يطابق كل ما تم تنفيذه من خلال الرمز في ملف index.ts
. هذا هو الشكل الذي من المفترض أن يبدو عليه ملف extension.yaml
المكتمل في الوقت الحالي:
extension.yaml
name: geohash-ext
version: 0.0.1
specVersion: v1beta # Firebase Extensions specification version (do not edit)
displayName: Latitude and Longitude to GeoHash converter
description: A converter for changing your Latitude and Longitude coordinates to geohashes.
license: Apache-2.0 # The license you want for the extension
author:
authorName: Sparky
url: https://github.com/Firebase
billingRequired: true
resources:
- name: locationUpdate
type: firebaseextensions.v1beta.function
properties:
eventTrigger:
eventType: providers/cloud.firestore/eventTypes/document.write
resource: projects/${PROJECT_ID}/databases/(default)/documents/users/{uid}
- name: callableHash
type: firebaseextensions.v1beta.function
properties:
httpsTrigger: {}
roles:
- role: datastore.user
reason: Allows the extension to read / write to your Firestore instance.
التحقّق من الحالة
في هذه المرحلة، تكون لديك الأجزاء الوظيفية الأولية من الإضافة، بحيث يمكنك تجربتها فعليًا باستخدام أدوات محاكاة Firebase.
- يمكنك استدعاء
npm run build
في مجلد الدوال ضمن مشروع الإضافات التي تم تنزيلها، إذا لم يسبق لك إجراء ذلك. - أنشِئ دليلاً جديدًا على النظام المضيف واربط هذا الدليل بمشروع Firebase باستخدام
firebase init
.
cd .. mkdir sample-proj cd sample-proj firebase init --project=projectID-or-alias
This command creates a `firebase.json` file in the directory. In the following steps, you push the configuration specified in this file to Firebase.
- من الدليل نفسه، شغِّل
firebase ext:install
. استبدِل/path/to/extension
بالمسار المطلق للدليل الذي يحتوي على ملفextension.yaml
.
firebase ext:install /path/to/extension
This command does two things:
- يطالبك بتحديد الإعدادات لمثيل الإضافة، ثم ينشئ ملف
*.env
يحتوي على معلومات الإعداد للمثيل. - تُضيف مثيل الإضافة إلى القسم
extensions
علىfirebase.json
. يعمل هذا الإجراء كخريطة لرقم تعريف المثيل لإصدار الإضافة. - بما أنّك تنشر المشروع محليًا، يمكنك تحديد أنّك تريد استخدام ملف محلي بدلاً من "مدير سر Google Cloud".
- ابدأ تشغيل أدوات محاكاة Firebase بالتهيئة الجديدة:
firebase emulators:start
- بعد تشغيل
emulators:start
، انتقِل إلى علامة التبويب Firestore في webview الخاص بالمحاكيات. - أضِف مستندًا إلى مجموعة
users
مع حقل رقمxv
وحقل رقمyv
.
- إذا تم تثبيت الإضافة بنجاح، ستنشئ الإضافة حقلاً جديدًا باسم "
hash
" في المستند.
إخلاء مساحة تخزين لتجنّب التعارضات
- بعد الانتهاء من الاختبار، ألغِ تثبيت الإضافة. ستُعدِّل رمز الإضافة ولا تريد أن تتعارض مع الإضافة الحالية لاحقًا.
تتيح الإضافات تثبيت إصدارات متعددة من الإضافة نفسها في آنٍ واحد، لذا يمكنك من خلال إلغاء التثبيت ضمان عدم وجود تعارض مع إضافة سبق تثبيتها.
firebase ext:uninstall geohash-ext
يعمل الحل الحالي، ولكن كما ذُكر في بداية المشروع، يوجد مفتاح واجهة برمجة تطبيقات غير قابل للتغيير لمحاكاة الاتصال بإحدى الخدمات. كيف يمكنك استخدام مفتاح واجهة برمجة التطبيقات الخاص بالمستخدم النهائي بدلاً من المفتاح الذي تم توفيره في الأصل؟ تابِع القراءة لمعرفة المزيد.
6- جعل مستخدم الإضافة قابلاً للضبط
في هذه المرحلة من الدرس التطبيقي حول الترميز، تتوفّر لديك إضافة تم ضبطها للاستخدام مع خطوات الإعداد المستندة إلى رأي للدوال التي كتبتها، ولكن ماذا لو أراد المستخدم استخدام خطوط الطول والعرض بدلاً من y وx للحقول التي تشير إلى الموقع الجغرافي على المستوى الديكارتي؟ أيضًا، كيف يمكنك جعل المستخدم النهائي يقدم مفتاح واجهة برمجة التطبيقات الخاص به، بدلاً من السماح له باستخدام مفتاح واجهة برمجة التطبيقات المقدم؟ يمكنك تجاوز الحصة المحدّدة لواجهة برمجة التطبيقات هذه بسرعة. في هذه الحالة، يمكنك إعداد المعلمات واستخدامها.
تحديد المَعلمات الأساسية في ملف extension.yaml
ابدأ بتحويل العناصر التي من المحتمل أن يكون لدى المطوِّرين إعدادات مخصّصة لها. ستكون العملية الأولى هي المعلمتَين XFIELD
وYFIELD
.
- في ملف
extension.yaml
، أضِف الرمز التالي الذي يستخدم مَعلمتَيXFIELD
وYFIELD
. تتوفّر هذه المَعلمات داخل سمة YAML المحدّدة سابقًا فيparams
:
extension.yaml
params:
- param: XFIELD
label: The X Field Name
description: >-
The X Field is also known as the **longitude** value. What does
your Firestore instance refer to as the X value or the longitude
value. If no value is specified, the extension searches for
field 'xv'.
type: string
validationRegex: ^\D([0-9a-zA-Z_.]{0,375})$
validationErrorMessage: >-
The field can only contain uppercase or lowercase letter, numbers,
_, and . characters and must be less than 1500 bytes long. The field
must also not start with a number.
default: xv
required: false
immutable: false
example: xv
- param: YFIELD
label: The Y Field Name
description: >-
The Y Field is also known as the **latitude** value. What does
your Firestore instance refer to as the Y value or the latitude
value. If no value is specified, the extension searches for
field 'yv'.
type: string
validationRegex: ^\D([0-9a-zA-Z_.]{0,375})$
validationErrorMessage: >-
The field can only contain uppercase or lowercase letter, numbers,
_, and . characters and must be less than 1500 bytes long. The field
must also not start with a number.
default: yv
required: false
immutable: false
example: yv
- تسمّي param المَعلمة بطريقة مرئية لك، منتج الإضافة. يمكنك استخدام هذه القيمة لاحقًا عند تحديد قيم المَعلمات.
- label هي معرّف يمكن للمستخدم قراءته لإطلاعه على وظيفة المَعلمة.
- description وصفًا تفصيليًا للقيمة. وبما أنّ هذا الإجراء يتوافق مع عملية markdown، فيمكن أن يؤدي إلى مستندات إضافية، أو يمكن أن يبرز كلمات قد تكون مهمة للمطوّر.
- تحدد type آلية الإدخال لكيفية ضبط المستخدم لقيمة المعلَمة. تتوفّر أنواع كثيرة من هذه المنتجات، بما في ذلك
string
وselect
وmultiSelect
وselectResource
وsecret
. للحصول على مزيد من المعلومات حول كل خيار من هذه الخيارات، يمكنك الاطّلاع على المستندات. - تقيد الطريقة VerifyationRegex إدخال المطوّر على قيمة تعبير عادي معيّنة (تستند في المثال إلى إرشادات اسم الحقل البسيطة المتوفّرة هنا). وإذا فشل ذلك...
- تُنبّه verificationationErrorMessage المطوّر إلى قيمة التعذُّر.
- default هي القيمة التي ستظهر إذا لم يُدخِل المطور أي نص.
- تعني الحالة مطلوب أنّ المطوّر غير مطالب بإدخال أي نص.
- غير قابل للتغيير تسمح لمطور البرامج بتعديل هذه الإضافة وتغيير هذه القيمة. في هذه الحالة، يجب أن يتمكّن المطوّر من تغيير أسماء الحقول مع تغيُّر متطلباتها.
- يوفر الحقل example فكرة عن الشكل الذي قد يبدو عليه الإدخال الصالح.
كان ذلك كثيرًا لفهمه!
- يتبقى لديك ثلاث مَعلمات أخرى يجب إضافتها إلى ملف
extension.yaml
قبل إضافة مَعلمة خاصة.
- param: INPUTPATH
label: The input document to listen to for changes
description: >-
This is the document where you write an x and y value to. Once
that document has received a value, it notifies the extension to
calculate a geohash and store that in an output document in a certain
field. This accepts function [wildcard parameters](https://firebase.google.com/docs/functions/firestore-events#wildcards-parameters)
type: string
validationRegex: ^[^/]+(/[^/]*/[^/]*)*/[^/]+$
validationErrorMessage: >-
This must point to a document path, not a collection path from the root
of the database. It must also not start or end with a '/' character.
required: true
immutable: false
example: users/{uid}
- param: OUTPUTFIELD
label: Geohash field
description: >-
This specifies the field in the output document to store the geohash in.
type: string
validationRegex: ^\D([0-9a-zA-Z_.]{0,375})$
validationErrorMessage: >-
The field can only contain uppercase or lowercase letter, numbers,
_, and . characters and must be less than 1500 bytes long. The field
must also not start with a number.
required: false
default: hash
immutable: false
example: hash
تحديد المَعلمات الحسّاسة
وعليك الآن إدارة مفتاح واجهة برمجة التطبيقات الذي يحدّده المستخدم. هذه سلسلة حساسة يجب عدم تخزينها في نص عادي في الدالة. بدلاً من ذلك، يمكنك تخزين هذه القيمة في مدير السحابة الإلكترونية السرّي. وهو موقع خاص في السحابة الإلكترونية يخزن الأسرار المشفرة ويمنع تسربها عن طريق الخطأ. ويتطلّب ذلك من المطوّر دفع رسوم مقابل استخدام هذه الخدمة، إلا أنّها توفّر طبقة أمان إضافية على مفاتيح واجهة برمجة التطبيقات، ما قد يحدّ من النشاط الاحتيالي. تنبه مستندات المستخدم المطوّر بأنّها خدمة مدفوعة، حتى لا يكون هناك أي مفاجآت في الفوترة. بشكل عام، يشبه الاستخدام موارد السلسلة الأخرى المذكورة أعلاه. الاختلاف الوحيد هو النوع الذي يُسمى secret
.
- في ملف
extension.yaml
، أضِف الرمز التالي:
extension.yaml
- param: APIKEY
label: GeohashService API Key
description: >-
Your geohash service API Key. Since this is a demo, and not a real
service, you can use : 1234567890.
type: secret
required: true
immutable: false
تعديل السمات resource
لاستخدام المَعلمات
وكما ذكرنا سابقًا، يحدّد المورد (وليس الدالة) كيفية تتبّع المورد، وبالتالي يجب تعديل مورد locationUpdate
من أجل استخدام المَعلمة الجديدة.
- في ملف
extension.yaml
، أضِف الرمز التالي:
extension.yaml
## Change from this
- name: locationUpdate
type: firebaseextensions.v1beta.function
properties:
eventTrigger:
eventType: providers/cloud.firestore/eventTypes/document.write
resource: projects/${PROJECT_ID}/databases/(default)/documents/users/{uid}]
## To this
- name: locationUpdate
type: firebaseextensions.v1beta.function
properties:
eventTrigger:
eventType: providers/cloud.firestore/eventTypes/document.write
resource: projects/${PROJECT_ID}/databases/(default)/documents/${INPUTPATH}
يُرجى التحقّق من الملف في "extension.yaml
".
- راجِع الملف
extension.yaml
. من المفترض أن تظهر بشكلٍ مشابه لما يلي:
extension.yaml
name: geohash-ext
version: 0.0.1
specVersion: v1beta # Firebase Extensions specification version (do not edit)
displayName: Latitude and Longitude to GeoHash converter
description: A converter for changing your Latitude and Longitude coordinates to geohashes.
license: Apache-2.0 # The license you want to use for the extension
author:
authorName: Sparky
url: https://github.com/Firebase
billingRequired: true
params:
- param: XFIELD
label: The X Field Name
description: >-
The X Field is also known as the **longitude** value. What does
your Firestore instance refer to as the X value or the longitude
value. If you don't provide a value for this field, the extension will use 'xv' as the default value.
type: string
validationRegex: ^\D([0-9a-zA-Z_.]{0,375})$
validationErrorMessage: >-
The field can only contain uppercase or lowercase letter, numbers,
_, and . characters and must be less than 1500 bytes long. The field
must also not start with a number.
default: xv
required: false
immutable: false
example: xv
- param: YFIELD
label: The Y Field Name
description: >-
The Y Field is also known as the **latitude** value. What does
your Firestore instance refer to as the Y value or the latitude
Value. If you don't provide a value for this field, the extension will use 'yv' as the default value.
type: string
validationRegex: ^\D([0-9a-zA-Z_.]{0,375})$
validationErrorMessage: >-
The field can only contain uppercase or lowercase letter, numbers,
_, and . characters and must be less than 1500 bytes long. The field
must also not start with a number.
default: yv
required: false
immutable: false
example: yv
- param: INPUTPATH
label: The input document to listen to for changes
description: >-
This is the document where you write an x and y value to. Once
that document has been modified, it notifies the extension to
compute a geohash and store that in an output document in a certain
field. This accepts function [wildcard parameters](https://firebase.google.com/docs/functions/firestore-events#wildcards-parameters)
type: string
validationRegex: ^[^/]+(/[^/]*/[^/]*)*/[^/]+$
validationErrorMessage: >-
This must point to a document path, not a collection path from the root
of the database. It must also not start or end with a '/' character.
required: true
immutable: false
example: users/{uid}
- param: OUTPUTFIELD
label: Geohash field
description: >-
This specifies the field in the output document to store the geohash in.
type: string
validationRegex: ^\D([0-9a-zA-Z_.]{0,375})$
validationErrorMessage: >-
The field can only contain uppercase or lowercase letter, numbers,
_, and . characters and must be less than 1500 bytes long. The field
must also not start with a number.
required: false
default: hash
immutable: false
example: hash
- param: APIKEY
label: GeohashService API Key
description: >-
Your geohash service API Key. Since this is a demo, and not a real
service, you can use : 1234567890.
type: secret
required: true
immutable: false
resources:
- name: locationUpdate
type: firebaseextensions.v1beta.function
properties:
eventTrigger:
eventType: providers/cloud.firestore/eventTypes/document.write
resource: projects/${PROJECT_ID}/databases/(default)/documents/${INPUTPATH}
- name: callableHash
type: firebaseextensions.v1beta.function
properties:
httpsTrigger: {}
roles:
- role: datastore.user
reason: Allows the extension to read / write to your Firestore instance.
مَعلمات الوصول في الرمز
والآن بعد أن تم ضبط جميع المَعلمات في ملف extension.yaml
، أضِفها إلى ملف index.ts
.
- في ملف
index.ts
، استبدِل القيم التلقائية بـprocess.env.PARAMETER_NAME
، الذي يسترجع قيم المَعلمات المناسبة ويعبئها في رمز الدالة المنشور في مشروع Firebase الخاص بالمطوّر.
index.ts
// Replace this:
const documentPath = "users/{uid}";
const xField = "xv";
const yField = "yv";
const apiKey = "1234567890";
const outputField = "hash";
// with this:
const documentPath = process.env.INPUTPATH!; // this value is ignored since its read from the resource
const xField = process.env.XFIELD!;
const yField = process.env.YFIELD!;
const apiKey = process.env.APIKEY!;
const outputField = process.env.OUTPUTFIELD!;
عادة، تريد إجراء عمليات تحقق فارغة باستخدام قيم متغير البيئة، ولكن في هذه الحالة، تثق في أنه تم نسخ قيم المعلمة بشكل صحيح. تم إعداد الرمز الآن ليعمل مع معلمات الإضافة.
7- إنشاء مستندات المستخدم
قبل اختبار الرمز على أدوات المحاكاة أو في سوق إضافات Firebase، يلزم توثيق الإضافة حتى يعرف المطورون ما سيحصلون عليه عند استخدام الإضافة.
- ابدأ بإنشاء ملف
PREINSTALL.md
، والذي يُستخدم لوصف الوظيفة وأي متطلبات أساسية للتثبيت والآثار المحتملة على الفوترة.
PREINSTALL.md
Use this extension to automatically convert documents with a latitude and
longitude to a geohash in your database. Additionally, this extension includes a callable function that allows users to make one-time calls
to convert an x,y coordinate into a geohash.
Geohashing is supported for latitudes between 90 and -90 and longitudes
between 180 and -180.
#### Third Party API Key
This extension uses a fictitious third-party API for calculating the
geohash. You need to supply your own API keys. (Since it's fictitious,
you can use 1234567890 as an API key).
#### Additional setup
Before installing this extension, make sure that you've [set up a Cloud
Firestore database](https://firebase.google.com/docs/firestore/quickstart) in your Firebase project.
After installing this extension, you'll need to:
- Update your client code to point to the callable geohash function if you
want to perform arbitrary geohashes.
Detailed information for these post-installation tasks are provided after
you install this extension.
#### Billing
To install an extension, your project must be on the [Blaze (pay as you
go) plan](https://firebase.google.com/pricing)
- This extension uses other Firebase and Google Cloud Platform services,
which have associated charges if you exceed the service's no-cost tier:
- Cloud Firestore
- Cloud Functions (Node.js 16+ runtime. [See
FAQs](https://firebase.google.com/support/faq#extensions-pricing))
- [Cloud Secret Manager](https://cloud.google.com/secret-manager/pricing)
- لتوفير الوقت في كتابة
README.md
لهذا المشروع، استخدم الطريقة الملائمة:
firebase ext:info . --markdown > README.md
تجمع هذه البيانات بين محتوى ملف PREINSTALL.md
والتفاصيل الإضافية حول إضافتك من ملف extension.yaml
.
وأخيرًا، أبلغ مطور الإضافة ببعض التفاصيل الإضافية المتعلقة بالإضافة التي تم تثبيتها للتو. قد يحصل مطوّر البرامج على بعض التعليمات والمعلومات الإضافية بعد إكمال التثبيت، وقد يحصل على بعض المهام التفصيلية لما بعد التثبيت، مثل إعداد رمز العميل هنا.
- أنشئ ملف
POSTINSTALL.md
، ثم أدرِج معلومات تثبيت المشاركة التالية:
POSTINSTALL.md
Congratulations on installing the geohash extension!
#### Function information
* **Firestore Trigger** - ${function:locationUpdate.name} was installed
and is invoked when both an x field (${param:XFIELD}) and y field
(${param:YFIELD}) contain a value.
* **Callable Trigger** - ${function:callableHash.name} was installed and
can be invoked by writing the following client code:
```javascript
import { getFunctions, httpsCallable } from "firebase/functions";
const functions = getFunctions();
const geoHash = httpsCallable(functions, '${function:callableHash.name}');
geoHash({ ${param:XFIELD}: -122.0840, ${param:YFIELD}: 37.4221 })
.then((result) => {
// Read result of the Cloud Function.
/** @type {any} */
const data = result.data;
const error = data.error;
if (error != null) {
console.error(`callable error : ${error}`);
}
const result = data.result;
console.log(result);
});
المراقبة
من بين أفضل الممارسات، يمكنك مراقبة نشاط الإضافة المثبّتة، بما في ذلك عمليات التحقق من سلامتها واستخدامها وسجلاتها.
The output rendering looks something like this when it's deployed:
<img src="img/82b54a5c6ca34b3c.png" alt="A preview of the latitude and longitude geohash converter extension in the firebase console" width="957.00" />
## Test the extension with the full configuration
Duration: 03:00
It's time to make sure that the user-configurable extension is working the way it is intended.
* Change into the functions folder and ensure that the latest compiled version of the extensions exists. In the extensions project functions directory, call:
```console
npm run build
يؤدي ذلك إلى إعادة تجميع الدوال حتى يصبح أحدث رمز مصدر جاهزًا للنشر إلى جانب الإضافة عند نشرها على المحاكي أو في Firebase مباشرةً.
بعد ذلك، أنشئ دليلاً جديدًا لاختبار الإضافة منه. بما أنّ الإضافة قد تم تطويرها من وظائف حالية، يجب عدم إجراء اختبار من المجلد الذي تم ضبط الإضافة فيه لأنّها تحاول أيضًا نشر الدوال وقواعد Firebase إلى جانبها.
التثبيت واختبار أدوات محاكاة Firebase
- أنشِئ دليلاً جديدًا على النظام المضيف واربط هذا الدليل بمشروع Firebase باستخدام
firebase init
.
mkdir sample-proj cd sample-proj firebase init --project=projectID-or-alias
- من هذا الدليل، شغِّل الإضافة "
firebase ext:install
" لتثبيت الإضافة. استبدِل/path/to/extension
بالمسار المطلق للدليل الذي يحتوي على ملفextension.yaml
. يؤدي ذلك إلى بدء عملية تثبيت الإضافة وإنشاء ملف.env
يحتوي على الإعدادات التي أجريتها قبل إرسال الإعدادات إلى Firebase أو إلى أدوات المحاكاة.
firebase ext:install /path/to/extension
- بما أنّك تنشر المشروع محليًا، عليك تحديد أنّك تريد استخدام ملف محلي بدلاً من "مدير سر Google Cloud".
- ابدأ تشغيل مجموعة المحاكي المحلي:
firebase emulators:start
التثبيت والاختبار باستخدام مشروع حقيقي في Firebase
يمكنك تثبيت الإضافة في مشروع فعلي على Firebase. يوصى باستخدام مشروع اختباري للاختبار. استخدِم سير عمل الاختبار هذا إذا كنت تريد اختبار التدفق الشامل للإضافة أو إذا لم يكن مشغّل الإضافة متوافقًا بعد مع مجموعة مُحاكي Firebase (اطّلِع على خيار محاكي الإضافات). تتيح أدوات المحاكاة حاليًا استخدام الدوال التي يتم تشغيلها عن طريق طلبات HTTP والدوال التي يتم تشغيلها في الخلفية لكل من Cloud Firestore و"قاعدة بيانات الوقت الفعلي" وPub/Sub.
- أنشِئ دليلاً جديدًا على النظام المضيف واربط هذا الدليل بمشروع Firebase باستخدام
firebase init
.
cd .. mkdir sample-proj cd sample-proj firebase init --project=projectID-or-alias
- بعد ذلك، شغِّل
firebase ext:install
من هذا الدليل لتثبيت الإضافة. استبدِل/path/to/extension
بالمسار المطلق للدليل الذي يحتوي على ملفextension.yaml
. يؤدي ذلك إلى بدء عملية تثبيت الإضافة وإنشاء ملف.env
يحتوي على الإعدادات التي أجريتها قبل إرسال الإعدادات إلى Firebase أو إلى أدوات المحاكاة.
firebase ext:install /path/to/extension
- بما أنّك تريد النشر في Firebase مباشرةً وتريد استخدام Google Cloud Secret Manager، عليك تفعيل Secret Manager API قبل تثبيت الإضافة.
- النشر إلى مشروع Firebase
firebase deploy
اختبار الإضافة
- بعد تشغيل
firebase deploy
أوfirebase emulators:start
، انتقِل إلى علامة التبويب Firestore في وحدة تحكُّم Firebase أو webview الخاص بالمحاكيات، حسب الحاجة. - أضِف مستندًا إلى المجموعة المحدّدة في الحقل
x
والحقلy
. في هذه الحالة، تتوفّر المستندات المعدَّلة فيu/{uid}
باستخدام الحقلx
بالقيمةxv
والحقلy
فيyv
.
- إذا نجحت في تثبيت الإضافة، ستنشئ الإضافة حقلاً جديدًا باسم
hash
في المستند بعد حفظ الحقلَين.
8- تهانينا
لقد نجحت في تحويل أول وظيفة في السحابة الإلكترونية إلى إضافة Firebase.
لقد أضفت ملف extension.yaml
واضبطه كي يتمكّن المطوّرون من اختيار طريقة نشر إضافتك. ثم أنشأت مستندات مستخدم توفر إرشادات حول ما يجب أن يفعله مطورو الإضافة قبل إعداد الإضافة والخطوات التي قد يحتاجون إلى اتخاذها بعد تثبيت الإضافة بنجاح.
أنت تعرف الآن الخطوات الرئيسية المطلوبة لتحويل إحدى وظائف Firebase إلى إضافة Firebase قابلة للتوزيع.