Google is committed to advancing racial equity for Black communities. See how.
ترجمت واجهة Cloud Translation API‏ هذه الصفحة.
Switch to English

مشغلات قاعدة البيانات

باستخدام وظائف السحاب ، يمكنك التعامل مع الأحداث في Firebase Realtime Database دون الحاجة إلى تحديث رمز العميل. تتيح لك وظائف السحاب تشغيل عمليات قاعدة بيانات Realtime مع امتيازات إدارية كاملة ، وتضمن معالجة كل تغيير في قاعدة بيانات Realtime بشكل فردي. يمكنك إجراء تغييرات قاعدة بيانات DataSnapshot Realtime عبر DataSnapshot أو عبر Admin SDK .

في دورة حياة نموذجية ، تقوم وظيفة Firebase Realtime Database بما يلي:

  1. ينتظر التغييرات على موقع معين لقاعدة بيانات Realtime.
  2. يتم تشغيله عند وقوع حدث وأداء مهامه (راجع ماذا يمكنني أن أفعل مع وظائف السحاب؟ للحصول على أمثلة لحالات الاستخدام).
  3. يستقبل كائن بيانات يحتوي على لقطة للبيانات المخزنة في المستند المحدد.

قم بتشغيل وظيفة قاعدة بيانات Realtime

إنشاء وظائف جديدة لأحداث قاعدة بيانات Realtime مع functions.database . للتحكم في وقت تشغيل الوظيفة ، حدد أحد معالجات الأحداث ، وحدد مسار قاعدة بيانات Realtime حيث ستستمع للأحداث.

قم بتعيين معالج الأحداث

تتيح لك الوظائف معالجة أحداث قاعدة بيانات Realtime على مستويين من الخصوصية ؛ يمكنك الاستماع خصيصًا لأحداث الإنشاء أو التحديث أو الحذف فقط ، أو يمكنك الاستماع إلى أي تغيير من أي نوع على المسار. تدعم Cloud Functions معالجات الأحداث هذه لقاعدة بيانات Realtime:

  • onWrite() ، والتي يتم onWrite() عند إنشاء البيانات أو تحديثها أو حذفها في قاعدة بيانات Realtime.
  • onCreate() ، والذي يتم onCreate() عند إنشاء بيانات جديدة في قاعدة بيانات Realtime.
  • onUpdate() ، والذي يتم onUpdate() عند تحديث البيانات في قاعدة بيانات Realtime.
  • onDelete() ، والذي يتم onDelete() عند حذف البيانات من قاعدة بيانات Realtime.

حدد المثيل والمسار

للتحكم في الوقت والمكان الذي يجب أن يتم فيه تشغيل وظيفتك ، اتصل ref(path) لتحديد مسار ، وحدد بشكل اختياري نسخة قاعدة بيانات Realtime مع instance('INSTANCE_NAME') . إذا لم تحدد مثيلًا ، فسيتم نشر الوظيفة إلى مثيل قاعدة بيانات Realtime الافتراضية لمشروع Firebase على سبيل المثال:

  • المثيل الافتراضي لقاعدة بيانات Realtime: functions.database.ref('/foo/bar')
  • المثال المسمى "my-app-db-2": functions.database.instance('my-app-db-2').ref('/foo/bar')

توجه هذه الأساليب وظيفتك للتعامل مع عمليات الكتابة في مسار معين داخل مثيل قاعدة بيانات Realtime. تتطابق مواصفات المسار مع جميع عمليات الكتابة التي تلمس المسار ، بما في ذلك عمليات الكتابة التي تحدث في أي مكان تحته. إذا قمت بتعيين المسار /foo/bar كـ /foo/bar ، فإنه يطابق الأحداث في كلا الموقعين:

  /foo/bar
 /foo/bar/baz/really/deep/path
 

في كلتا الحالتين ، يفسر Firebase أن الحدث يقع في /foo/bar ، وأن بيانات الحدث تتضمن البيانات القديمة والجديدة على /foo/bar . إذا كانت بيانات الحدث قد تكون كبيرة ، ففكر في استخدام وظائف متعددة في مسارات أعمق بدلاً من وظيفة واحدة بالقرب من جذر قاعدة البيانات. للحصول على أفضل أداء ، اطلب البيانات فقط في أعمق مستوى ممكن.

يمكنك تحديد مكون مسار كحرف بدل بإحاطته بأقواس متعرجة ؛ ref('foo/{bar}') يتطابق مع أي تابع لـ /foo . تتوفر قيم مكونات مسار حرف البدل هذه داخل كائن EventContext.params . في هذا المثال ، تكون القيمة متاحة ك event.params.bar .

يمكن أن تتطابق المسارات مع أحرف البدل مع أحداث متعددة من كتابة واحدة. إدراج

 {
  "foo": {
    "hello": "world",
    "firebase": "functions"
  }
}
 

يطابق المسار "/foo/{bar}" مرتين: مرة باستخدام "hello": "world" ومرة أخرى مع "firebase": "functions" .

معالجة بيانات الأحداث

عند معالجة حدث قاعدة بيانات Realtime ، يكون كائن البيانات الذي تم إرجاعه هو DataSnapshot . بالنسبة onWrite أو onUpdate ، فإن المعلمة الأولى هي كائن Change يحتوي على لقطتين تمثلان حالة البيانات قبل وبعد حدث التشغيل. ل onCreate و onDelete الأحداث، الكائن البيانات التي تم إرجاعها لقطة من البيانات التي تم إنشاؤها أو حذفها.

في هذا المثال ، تقوم الوظيفة باسترداد لقطة المسار المحدد snap ، وتحويل السلسلة في ذلك الموقع إلى أحرف كبيرة ، وكتابة تلك السلسلة المعدلة إلى قاعدة البيانات:

// Listens for new messages added to /messages/:pushId/original and creates an
// uppercase version of the message to /messages/:pushId/uppercase
exports.makeUppercase = functions.database.ref('/messages/{pushId}/original')
    .onCreate((snapshot, context) => {
      // Grab the current value of what was written to the Realtime Database.
      const original = snapshot.val();
      console.log('Uppercasing', context.params.pushId, original);
      const uppercase = original.toUpperCase();
      // You must return a Promise when performing asynchronous tasks inside a Functions such as
      // writing to the Firebase Realtime Database.
      // Setting an "uppercase" sibling in the Realtime Database returns a Promise.
      return snapshot.ref.parent.child('uppercase').set(uppercase);
    });

الوصول إلى معلومات مصادقة المستخدم

من EventContext.auth و EventContext.authType ، يمكنك الوصول إلى معلومات المستخدم ، بما في ذلك الأذونات ، للمستخدم الذي قام بتشغيل وظيفة. يمكن أن يكون هذا مفيدًا لفرض قواعد الأمان ، مما يسمح لوظيفتك بإكمال عمليات مختلفة بناءً على مستوى أذونات المستخدم:

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

exports.simpleDbFunction = functions.database.ref('/path')
    .onCreate((snap, context) => {
      if (context.authType === 'ADMIN') {
        // do something
      } else if (context.authType === 'USER') {
        console.log(snap.val(), 'written by', context.auth.uid);
      }
    });
 

يمكنك أيضًا الاستفادة من معلومات مصادقة المستخدم "لانتحال هوية" مستخدم وإجراء عمليات الكتابة نيابة عن المستخدم. تأكد من حذف مثيل التطبيق كما هو موضح أدناه من أجل منع مشاكل التزامن:

 exports.impersonateMakeUpperCase = functions.database.ref('/messages/{pushId}/original')
    .onCreate((snap, context) => {
      const appOptions = JSON.parse(process.env.FIREBASE_CONFIG);
      appOptions.databaseAuthVariableOverride = context.auth;
      const app = admin.initializeApp(appOptions, 'app');
      const uppercase = snap.val().toUpperCase();
      const ref = snap.ref.parent.child('uppercase');

      const deleteApp = () => app.delete().catch(() => null);

      return app.database().ref(ref).set(uppercase).then(res => {
        // Deleting the app is necessary for preventing concurrency leaks
        return deleteApp().then(() => res);
      }).catch(err => {
        return deleteApp().then(() => Promise.reject(err));
      });
    });
 

قراءة القيمة السابقة

يحتوي الكائن Change على خاصية before تتيح لك فحص ما تم حفظه في قاعدة بيانات Realtime قبل الحدث. تقوم الخاصية before بإرجاع DataSnapshot حيث DataSnapshot جميع الأساليب (على سبيل المثال ، val() ووجود exists() ) إلى القيمة السابقة. يمكنك قراءة القيمة الجديدة مرة أخرى إما باستخدام DataSnapshot الأصلي أو قراءة خاصية ما after . هذه الخاصية في أي Change هي DataSnapshot أخرى تمثل حالة البيانات بعد وقوع الحدث.

على سبيل المثال ، يمكن استخدام الخاصية before للتأكد من أن الدالة لا تزيد إلا عن نص كبير عند إنشائها لأول مرة:

 exports.makeUppercase = functions.database.ref('/messages/{pushId}/original')
    .onWrite((change, context) => {
      // Only edit data when it is first created.
      if (change.before.exists()) {
        return null;
      }
      // Exit when the data is deleted.
      if (!change.after.exists()) {
        return null;
      }
      // Grab the current value of what was written to the Realtime Database.
      const original = change.after.val();
      console.log('Uppercasing', context.params.pushId, original);
      const uppercase = original.toUpperCase();
      // You must return a Promise when performing asynchronous tasks inside a Functions such as
      // writing to the Firebase Realtime Database.
      // Setting an "uppercase" sibling in the Realtime Database returns a Promise.
      return change.after.ref.parent.child('uppercase').set(uppercase);
    });