Catch up on everything we announced at this year's Firebase Summit. Learn more

Kích hoạt cơ sở dữ liệu

Với Chức năng đám mây, bạn có thể xử lý các sự kiện trong Cơ sở dữ liệu thời gian thực của Firebase mà không cần cập nhật mã ứng dụng khách. Chức năng đám mây cho phép bạn chạy các hoạt động Cơ sở dữ liệu thời gian thực với đầy đủ các đặc quyền quản trị và đảm bảo rằng mỗi thay đổi đối với Cơ sở dữ liệu thời gian thực được xử lý riêng lẻ. Bạn có thể làm căn cứ hỏa lực Realtime Cơ sở dữ liệu thay đổi qua DataSnapshot hoặc thông qua SDK quản trị .

Trong một vòng đời điển hình, chức năng Cơ sở dữ liệu thời gian thực của Firebase thực hiện những việc sau:

  1. Chờ các thay đổi đối với một vị trí Cơ sở dữ liệu thời gian thực cụ thể.
  2. Triggers khi một sự kiện xảy ra và thực hiện nhiệm vụ của mình (xem Những gì tôi có thể làm với Cloud Chức năng? Cho ví dụ về các trường hợp sử dụng).
  3. Nhận một đối tượng dữ liệu có chứa ảnh chụp nhanh của dữ liệu được lưu trữ trong tài liệu được chỉ định.

Kích hoạt chức năng Cơ sở dữ liệu thời gian thực

Tạo chức năng mới cho các sự kiện Cơ sở dữ liệu thời gian thực với functions.database . Để kiểm soát khi nào hàm kích hoạt, hãy chỉ định một trong các trình xử lý sự kiện và chỉ định đường dẫn Cơ sở dữ liệu thời gian thực nơi nó sẽ lắng nghe các sự kiện.

Đặt trình xử lý sự kiện

Các chức năng cho phép bạn xử lý các sự kiện Cơ sở dữ liệu thời gian thực ở hai cấp độ cụ thể; bạn có thể nghe cụ thể chỉ các sự kiện tạo, cập nhật hoặc xóa hoặc bạn có thể nghe bất kỳ thay đổi nào dưới bất kỳ hình thức nào đối với đường dẫn. Chức năng đám mây hỗ trợ các trình xử lý sự kiện này cho Cơ sở dữ liệu thời gian thực:

  • onWrite() , mà trigger khi dữ liệu được tạo ra, cập nhật, hoặc xóa trong cơ sở dữ liệu thời gian thực.
  • onCreate() , mà trigger khi dữ liệu mới được tạo ra trong cơ sở dữ liệu thời gian thực.
  • onUpdate() , mà trigger khi dữ liệu được cập nhật trong cơ sở dữ liệu thời gian thực.
  • onDelete() , mà trigger khi dữ liệu bị xóa khỏi cơ sở dữ liệu thời gian thực.

Chỉ định phiên bản và đường dẫn

Để kiểm soát khi nào và nơi chức năng của bạn nên kích hoạt, gọi ref(path) để xác định một con đường, và tùy chọn chỉ định một cơ sở dữ liệu Ví dụ Realtime với instance('INSTANCE_NAME') . Nếu bạn không chỉ định một phiên bản, hàm sẽ triển khai phiên bản Realtime Database mặc định cho dự án Firebase. Ví dụ:

  • Mặc định dụ Cơ sở dữ liệu thời gian thực: functions.database.ref('/foo/bar')
  • Ví dụ đặt tên là "my-app-db-2": functions.database.instance('my-app-db-2').ref('/foo/bar')

Các phương thức này hướng chức năng của bạn xử lý việc ghi tại một đường dẫn nhất định trong phiên bản Cơ sở dữ liệu thời gian thực. Thông số kỹ thuật con đường phù hợp với tất cả các ghi rằng chạm vào một con đường, trong đó có ghi điều đó xảy ra bất cứ nơi nào bên dưới nó. Nếu bạn thiết lập đường dẫn cho chức năng của bạn như /foo/bar , nó phù hợp với sự kiện tại cả hai địa điểm:

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

Trong cả hai trường hợp, diễn giải căn cứ hỏa lực mà sự kiện xảy ra tại /foo/bar , và dữ liệu sự kiện bao gồm các dữ liệu cũ và mới tại /foo/bar . Nếu dữ liệu sự kiện có thể lớn, hãy xem xét sử dụng nhiều hàm ở các đường dẫn sâu hơn thay vì một hàm duy nhất gần gốc cơ sở dữ liệu của bạn. Để có hiệu suất tốt nhất, chỉ yêu cầu dữ liệu ở mức sâu nhất có thể.

Bạn có thể chỉ định một thành phần đường dẫn dưới dạng ký tự đại diện bằng cách bao quanh nó bằng dấu ngoặc nhọn; ref('foo/{bar}') phù hợp với bất kỳ đứa trẻ /foo . Các giá trị của các thành phần con đường ký tự đại diện có sẵn trong EventContext.params đối tượng của chức năng của bạn. Trong ví dụ này, giá trị có sẵn như là context.params.bar .

Các đường dẫn có ký tự đại diện có thể khớp với nhiều sự kiện từ một lần ghi. Một phụ trang của

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

phù hợp với con đường "/foo/{bar}" hai lần: một lần với "hello": "world" và một lần nữa với "firebase": "functions" .

Xử lý dữ liệu sự kiện

Khi xử lý một sự kiện Cơ sở dữ liệu thời gian thực, các đối tượng dữ liệu trả về là một DataSnapshot . Đối với onWrite hoặc onUpdate sự kiện, tham số đầu tiên là một Change đối tượng có chứa hai bức ảnh chụp mà đại diện cho nhà nước số liệu trước và sau sự kiện kích hoạt. Đối với onCreateonDelete sự kiện, đối tượng dữ liệu trả về là một bản chụp của các dữ liệu được tạo ra hoặc xóa.

Trong ví dụ này, hàm lấy ảnh chụp cho đường dẫn cụ thể như snap , chuyển đổi chuỗi tại vị trí đó thành chữ hoa, và viết rằng biến đổi chuỗi cơ sở dữ liệu:

// 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();
      functions.logger.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);
    });

Truy cập thông tin xác thực người dùng

Từ EventContext.authEventContext.authType , bạn có thể truy cập vào thông tin người dùng, bao gồm cả quyền, cho người sử dụng đã làm hiển thị một hàm. Điều này có thể hữu ích để thực thi các quy tắc bảo mật, cho phép chức năng của bạn hoàn thành các hoạt động khác nhau dựa trên cấp độ quyền của người dùng:

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);
      }
    });

Ngoài ra, bạn có thể tận dụng thông tin xác thực người dùng để "mạo danh" người dùng và thực hiện các thao tác ghi thay mặt người dùng. Đảm bảo xóa phiên bản ứng dụng như được hiển thị bên dưới để ngăn các vấn đề về đồng thời:

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));
      });
    });

Đọc giá trị trước đó

Các Change đối tượng có before tài sản đó cho phép bạn kiểm tra những gì đã được lưu vào cơ sở dữ liệu thời gian thực trước sự kiện. Các before trở lại sở hữu một DataSnapshot nơi mà tất cả các phương pháp (ví dụ, val()exists() ) đề cập đến giá trị trước đó. Bạn có thể đọc các giá trị mới một lần nữa bằng cách sử dụng bản gốc DataSnapshot hoặc đọc after tài sản. Sở hữu trên bất kỳ này Change là một DataSnapshot đại diện cho trạng thái của dữ liệu sau khi sự kiện này xảy ra.

Ví dụ, before bất động sản có thể được sử dụng để đảm bảo chức năng chỉ uppercases văn bản khi nó lần đầu tiên được tạo ra:

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);
    });