Firebase Admin SDK là một tập hợp các thư viện máy chủ cho phép bạn tương tác với Firebase từ các môi trường có đặc quyền để thực hiện các thao tác như chạy truy vấn và thay đổi trên một Firebase Data Connect dịch vụ để quản lý dữ liệu hàng loạt và các thao tác khác có đặc quyền cấp cao và thông tin đăng nhập được nhập vai.
Admin SDK cung cấp cho bạn một API để gọi các thao tác ở cả chế độ đọc/ghi và chế độ chỉ có thể đọc. Với các thao tác chỉ đọc, bạn có thể yên tâm triển khai các hàm quản trị không thể sửa đổi dữ liệu trong cơ sở dữ liệu.
Thiết lập SDK dành cho quản trị viên
Để bắt đầu sử dụng với Firebase Data Connect trên máy chủ, trước tiên, bạn cần cài đặt và thiết lập Admin SDK cho Node.js.
Khởi chạy SDK dành cho quản trị viên trong tập lệnh
Để khởi chạy SDK, hãy nhập các tiện ích Data Connect và khai báo mã dịch vụ dự án cũng như vị trí.
import { initializeApp } from 'firebase-admin/app';
import { getDataConnect } from 'firebase-admin/data-connect';
// If you'd like to use OAuth2 flows and other credentials to log in,
// visit https://firebase.google.com/docs/admin/setup#initialize-sdk
// for alternative ways to initialize the SDK.
const app = initializeApp();
const dataConnect = getDataConnect({
serviceId: 'serviceId',
location: 'us-west2'
});
Thiết kế truy vấn và thay đổi để sử dụng với Admin SDK
Admin SDK rất hữu ích để chạy các thao tác Data Connect, hãy cân nhắc những điều sau.
Tìm hiểu về SDK và chỉ thị thao tác @auth(level: NO_ACCESS)
Vì Admin SDK hoạt động với các đặc quyền, nên SDK này có thể thực thi mọi
truy vấn và thay đổi của bạn bất kể cấp truy cập được thiết lập bằng các @auth chỉ thị, bao gồm cả cấp NO_ACCESS.
Nếu cùng với các thao tác của ứng dụng, bạn sắp xếp các truy vấn và thay đổi quản trị trong các tệp nguồn .gql để nhập vào tập lệnh quản trị, thì Firebase khuyên bạn nên đánh dấu các thao tác quản trị mà không có cấp truy cập uỷ quyền nào hoặc có thể rõ ràng hơn và đặt các thao tác đó thành NO_ACCESS. Dù bằng cách nào, điều này cũng ngăn các thao tác như vậy được thực thi từ ứng dụng hoặc trong các bối cảnh không có đặc quyền khác.
Sử dụng SDK với trình mô phỏng Data Connect
Trong môi trường nguyên mẫu và thử nghiệm, bạn có thể hữu ích khi thực hiện việc gieo dữ liệu và các thao tác khác trên dữ liệu địa phương. Admin SDK giúp bạn đơn giản hoá quy trình làm việc vì có thể bỏ qua quá trình xác thực và uỷ quyền cho các luồng cục bộ. (Bạn cũng có thể chọn tham gia tuân thủ cấu hình xác thực và uỷ quyền của các thao tác bằng cách mạo danh người dùng.)
Firebase Admin SDK sẽ tự động kết nối với trình mô phỏng Data Connect
khi biến môi trường DATA_CONNECT_EMULATOR_HOST được thiết lập:
export DATA_CONNECT_EMULATOR_HOST="127.0.0.1:9399"
Để biết thêm thông tin, hãy xem các bài viết sau:
- Hướng dẫn về việc gieo dữ liệu trong quá trình phát triển cục bộ
- Tài liệu về trình mô phỏng Data Connect.
Chạy các thao tác quản trị
Admin SDK được cung cấp cho các thao tác có đặc quyền trên dữ liệu quan trọng của bạn.
Admin SDK cung cấp 3 tập hợp API:
- SDK quản trị được tạo, là các SDK an toàn về kiểu được tạo từ các định nghĩa
gqltheo cùng một cách mà bạn tạo SDK ứng dụng. - Một giao diện chung để chạy các thao tác GraphQL tuỳ ý, trong đó mã của bạn triển khai các truy vấn và thay đổi, đồng thời truyền các truy vấn và thay đổi đó đến phương thức đọc-ghi
executeGraphqlhoặc phương thức chỉ đọcexecuteGraphqlRead. - Một giao diện chuyên biệt cho các thao tác dữ liệu hàng loạt, thay vì
các phương thức
executeGraphqlchung, sẽ hiển thị các phương thức dành riêng cho các thao tác thay đổi:insert,insertMany,upsertvàupsertMany.
Quản lý dữ liệu bằng các SDK được tạo
Bạn tạo SDK quản trị
từ các định nghĩa gql theo cùng một cách mà bạn tạo SDK ứng dụng.
SDK quản trị được tạo chứa các giao diện và hàm tương ứng với các định nghĩa gql, mà bạn có thể dùng để thực hiện các thao tác trên cơ sở dữ liệu. Ví dụ: giả sử bạn đã tạo một SDK cho cơ sở dữ liệu bài hát, cùng với một truy vấn getSongs:
import { initializeApp } from "firebase-admin/app";
import { getSongs } from "@dataconnect/admin-generated";
const adminApp = initializeApp();
const songs = await getSongs(
{ limit: 4 },
{ impersonate: { unauthenticated: true } }
);
Hoặc để chỉ định cấu hình trình kết nối:
import { initializeApp } from "firebase-admin/app";
import { getDataConnect } from "firebase-admin/data-connect";
import {
connectorConfig,
getSongs,
} from "@dataconnect/admin-generated";
const adminApp = initializeApp();
const adminDc = getDataConnect(connectorConfig);
const songs = await getSongs(
adminDc,
{ limit: 4 },
{ impersonate: { unauthenticated: true } }
);
Nhập vai người dùng chưa xác thực
Admin SDK được dùng để chạy từ các môi trường đáng tin cậy và do đó có quyền truy cập không hạn chế vào cơ sở dữ liệu của bạn.
Khi chạy các thao tác công khai bằng SDK quản trị, bạn nên tránh chạy thao tác với đầy đủ đặc quyền quản trị viên (tuân theo nguyên tắc về đặc quyền tối thiểu). Thay vào đó, bạn nên chạy thao tác dưới dạng người dùng được nhập vai (xem phần tiếp theo) hoặc dưới dạng người dùng chưa xác thực được nhập vai.
Người dùng chưa xác thực chỉ có thể chạy các thao tác được đánh dấu là PUBLIC.
Trong ví dụ trên, truy vấn getSongs được thực thi dưới dạng người dùng chưa xác thực.
Nhập vai người dùng
Bạn cũng có thể thực hiện các thao tác thay mặt cho những người dùng cụ thể bằng cách truyền một phần hoặc
toàn bộ mã thông báo Firebase Authentication trong tuỳ chọn impersonate; tối thiểu, bạn
phải chỉ định Mã nhận dạng người dùng của người dùng trong yêu cầu xác nhận sub. (Đây là cùng một giá trị với giá trị máy chủ
auth.uid mà
bạn có thể tham chiếu trong các thao tác GraphQL.)Data Connect
Khi bạn nhập vai người dùng, thao tác sẽ chỉ thành công nếu dữ liệu người dùng mà bạn cung cấp vượt qua các bước kiểm tra xác thực được chỉ định trong định nghĩa GraphQL.
Nếu bạn đang gọi SDK được tạo từ một điểm cuối có thể truy cập công khai, thì điều quan trọng là điểm cuối đó phải yêu cầu xác thực và bạn phải xác thực tính toàn vẹn của mã thông báo xác thực trước khi sử dụng mã thông báo đó để mạo danh người dùng.
Khi sử dụng có thể gọi Cloud Functions, mã thông báo xác thực sẽ tự động được xác minh và bạn có thể sử dụng mã thông báo đó như trong ví dụ sau:
import { HttpsError, onCall } from "firebase-functions/https";
export const callableExample = onCall(async (req) => {
const authClaims = req.auth?.token;
if (!authClaims) {
throw new HttpsError("unauthenticated", "Unauthorized");
}
const favoriteSongs = await getMyFavoriteSongs(
undefined,
{ impersonate: { authClaims } }
);
// ...
});
Nếu không, hãy sử dụng Admin SDK's verifyIdToken phương thức để xác thực và giải mã
mã thông báo xác thực. Ví dụ: giả sử điểm cuối của bạn được triển khai dưới dạng một
hàm HTTP thuần tuý và bạn đã truyền mã thông báo Firebase Authentication đến điểm cuối bằng tiêu đề authorization, như thường lệ:
import { getAuth } from "firebase-admin/auth";
import { onRequest } from "firebase-functions/https";
const auth = getAuth();
export const httpExample = onRequest(async (req, res) => {
const token = req.header("authorization")?.replace(/^bearer\s+/i, "");
if (!token) {
res.sendStatus(401);
return;
}
let authClaims;
try {
authClaims = await auth.verifyIdToken(token);
} catch {
res.sendStatus(401);
return;
}
const favoriteSongs = await getMyFavoriteSongs(
undefined,
{ impersonate: { authClaims } }
);
// ...
});
Chỉ khi thực hiện các tác vụ quản trị thực sự, chẳng hạn như di chuyển dữ liệu, từ một môi trường an toàn, không thể truy cập công khai, bạn mới nên chỉ định một mã nhận dạng người dùng không bắt nguồn từ một nguồn có thể xác minh:
// Never do this if end users can initiate execution of the code!
const favoriteSongs = await getMyFavoriteSongs(
undefined,
{ impersonate: { authClaims } }
);
Chạy với quyền truy cập không hạn chế
Nếu bạn đang thực hiện một thao tác yêu cầu quyền cấp quản trị, hãy bỏ qua tham số nhập vai khỏi lệnh gọi:
await upsertSong(adminDc, {
title: songTitle_one,
instrumentsUsed: [Instrument.VOCAL],
});
Một thao tác được gọi theo cách này có quyền truy cập hoàn toàn vào cơ sở dữ liệu. Nếu bạn có các truy vấn hoặc thay đổi chỉ dùng cho mục đích quản trị, thì bạn nên xác định các truy vấn hoặc thay đổi đó bằng chỉ thị @auth(level: NO_ACCESS). Việc này đảm bảo rằng chỉ những người gọi cấp quản trị mới có thể thực thi các thao tác này.
Quản lý dữ liệu bằng các phương thức executeGraphql
Nếu cần thực thi các thao tác một lần mà bạn chưa xác định gql
các thay đổi hoặc truy vấn, bạn có thể sử dụng phương thức executeGraphql hoặc phương thức chỉ đọc
executeGraphqlRead.
Nhập vai người dùng chưa xác thực
Khi chạy các thao tác công khai bằng SDK quản trị, bạn nên tránh chạy thao tác với đầy đủ đặc quyền quản trị viên (tuân theo nguyên tắc về đặc quyền tối thiểu). Thay vào đó, bạn nên chạy thao tác dưới dạng người dùng được nhập vai
(xem phần tiếp theo) hoặc dưới dạng người dùng chưa xác thực được nhập vai. Người dùng chưa xác thực chỉ có thể chạy các thao tác được đánh dấu là PUBLIC.
// Query to get posts, with authentication level PUBLIC
const queryGetPostsImpersonation = `
query getPosts @auth(level: PUBLIC) {
posts {
description
}
}`;
// Attempt to access data as an unauthenticated user
const optionsUnauthenticated: GraphqlOptions<undefined> = {
impersonate: {
unauthenticated: true
}
};
// executeGraphql with impersonated unauthenticated user scope
const gqlResponse = await dataConnect.executeGraphql<UserData, undefined>(queryGetPostsImpersonation, optionsUnauthenticated);
Nhập vai người dùng
Ngoài ra, có những trường hợp sử dụng mà bạn muốn tập lệnh sửa đổi dữ liệu người dùng dựa trên thông tin đăng nhập bị hạn chế, thay mặt cho một người dùng cụ thể. Phương pháp này tuân theo nguyên tắc về đặc quyền tối thiểu.
Để sử dụng giao diện này, hãy thu thập thông tin từ mã thông báo xác thực JWT tuỳ chỉnh tuân theo định dạng mã thông báo Authentication. Hãy xem thêm hướng dẫn về mã thông báo tuỳ chỉnh.
// Get the current user's data
const queryGetUserImpersonation = `
query getUser @auth(level: USER) {
user(key: {uid_expr: "auth.uid"}) {
id,
name
}
}`;
// Impersonate a user with the specified auth claims
const optionsAuthenticated: GraphqlOptions<undefined> = {
impersonate: {
authClaims: {
sub: 'QVBJcy5ndXJ1'
}
}
};
// executeGraphql with impersonated authenticated user scope
const gqlResponse = await dataConnect.executeGraphql<UserData, undefined>(queryGetUserImpersonation, optionsAuthenticated);
// gqlResponse -> { "data": { "user": { "id": "QVBJcy5ndXJ1", "name": "Fred" } } }
Sử dụng thông tin đăng nhập quản trị
Nếu bạn đang thực hiện một thao tác yêu cầu quyền cấp quản trị, hãy bỏ qua tham số nhập vai khỏi lệnh gọi:
// User can be publicly accessible, or restricted to admins
const query = "query getProfile(id: AuthID) { user(id: $id) { id name } }";
interface UserData {
user: {
id: string;
name: string;
};
}
export interface UserVariables {
id: string;
}
const options:GraphqlOptions<UserVariables> = { variables: { id: "QVBJcy5ndXJ1" } };
// executeGraphql
const gqlResponse = await dataConnect.executeGraphql<UserData, UserVariables>(query, options);
// executeGraphqlRead (similar to previous sample but only for read operations)
const gqlResponse = await dataConnect.executeGraphqlRead<UserData, UserVariables>(query, options);
// gqlResponse -> { "data": { "user": { "id": "QVBJcy5ndXJ1", "name": "Fred" } } }
Một thao tác được gọi theo cách này có quyền truy cập hoàn toàn vào cơ sở dữ liệu. Nếu bạn có các truy vấn hoặc thay đổi chỉ dùng cho mục đích quản trị, thì bạn nên xác định các truy vấn hoặc thay đổi đó bằng chỉ thị @auth(level: NO_ACCESS). Việc này đảm bảo rằng chỉ những người gọi cấp quản trị mới có thể thực thi các thao tác này.
Thực hiện các thao tác dữ liệu hàng loạt
Firebase khuyên bạn nên sử dụng Admin SDK cho các thao tác dữ liệu hàng loạt trên cơ sở dữ liệu phát hành công khai.
SDK cung cấp các phương thức sau để xử lý dữ liệu hàng loạt. Từ các đối số được cung cấp, mỗi phương thức sẽ tạo và thực thi một thay đổi GraphQL.
// Methods of the bulk operations API
// dc is a Data Connect admin instance from getDataConnect
const resp = await dc.insert("movie" /*table name*/, data[0]);
const resp = await dc.insertMany("movie" /*table name*/, data);
const resp = await dc.upsert("movie" /*table name*/, data[0]);
const resp = await dc.upsertMany("movie" /*table name*/, data);
Lưu ý về hiệu suất cho các thao tác hàng loạt
Mỗi yêu cầu gửi đến phần phụ trợ sẽ phát sinh một chuyến khứ hồi đến Cloud SQL, vì vậy, bạn càng tạo lô nhiều thì thông lượng càng cao.
Tuy nhiên, kích thước lô càng lớn thì câu lệnh SQL được tạo càng dài. Khi đạt đến giới hạn độ dài câu lệnh SQL PostgreSQL, bạn sẽ gặp lỗi.
Trong thực tế, hãy thử nghiệm để tìm kích thước lô phù hợp cho khối lượng công việc của bạn.
Tiếp theo là gì?
- Tìm hiểu về cách gieo dữ liệu vào cơ sở dữ liệu bằng Admin SDK
- Xem lại API cho Admin SDK.
- Sử dụng Firebase CLI và Google Cloud console cho các thao tác quản lý dự án khác, chẳng hạn như quản lý lược đồ và trình kết nối cũng như quản lý dịch vụ và cơ sở dữ liệu.