Die Firebase Admin SDK ist eine Reihe von Serverbibliotheken, mit denen Sie in privilegierten Umgebungen mit Firebase interagieren können, um Aktionen wie das Ausführen von Abfragen und Mutationen für einen Firebase Data Connect-Dienst zur Massendatenverwaltung und andere Vorgänge mit erhöhten Berechtigungen und imitierten Anmeldedaten auszuführen.
Die Admin SDK bietet eine API zum Aufrufen von Vorgängen im Lese-/Schreibmodus und im schreibgeschützten Modus. Mit den schreibgeschützten Vorgängen können Sie administrative Funktionen implementieren, die keine Daten in Ihren Datenbanken ändern können.
Admin SDK einrichten
Wenn Sie Firebase Data Connect auf Ihrem Server verwenden möchten, müssen Sie zuerst Admin SDK für Node.js installieren und einrichten.
Admin SDK in Ihren Skripts initialisieren
Um das SDK zu initialisieren, importieren Sie die Data Connect-Erweiterungen und deklarieren Sie die Dienst-ID und den Standort Ihres Projekts.
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'
});
Abfragen und Mutationen für die Verwendung mit dem Admin SDK entwerfen
Admin SDK ist nützlich, um Data Connect-Vorgänge auszuführen. Dabei sind die folgenden Aspekte zu berücksichtigen.
SDK und @auth(level: NO_ACCESS)-Vorgangsanweisung verstehen
Da Admin SDK mit Berechtigungen arbeitet, können damit alle Ihre Abfragen und Mutationen unabhängig von den mit @auth-Anweisungen festgelegten Zugriffsebenen ausgeführt werden, einschließlich der Ebene NO_ACCESS.
Wenn Sie neben Ihren Clientvorgängen Ihre administrativen Abfragen und Mutationen in .gql-Quelldateien für den Import in administrative Skripts organisieren, empfiehlt Firebase, die administrativen Vorgänge ohne Autorisierungszugriffsebene zu kennzeichnen oder sie expliziter als NO_ACCESS festzulegen. In beiden Fällen wird verhindert, dass solche Vorgänge von Clients oder in anderen nicht privilegierten Kontexten ausgeführt werden.
SDK mit dem Data Connect-Emulator verwenden
In Prototyp- und Testumgebungen kann es hilfreich sein, Daten-Seeding und andere Vorgänge für lokale Daten auszuführen. Mit Admin SDK können Sie Ihre Workflows vereinfachen, da die Authentifizierung und Autorisierung für lokale Abläufe ignoriert werden kann. Sie können auch explizit zustimmen, dass die Authentifizierungs- und Autorisierungskonfiguration Ihrer Vorgänge mit der Identitätsübernahme von Nutzern übereinstimmt.
Die Firebase Admin SDKs stellen automatisch eine Verbindung zum Data Connect-Emulator her, wenn die Umgebungsvariable DATA_CONNECT_EMULATOR_HOST festgelegt ist:
export DATA_CONNECT_EMULATOR_HOST="127.0.0.1:9399"
Weitere Informationen finden Sie unter:
Verwaltungsvorgänge ausführen
Die Admin SDK wird für privilegierte Vorgänge für Ihre wichtigen Daten bereitgestellt.
Das Admin SDK bietet drei Gruppen von APIs:
- Generierte Admin-SDKs: Das sind typsichere SDKs, die aus Ihren
gql-Definitionen generiert werden, genau wie Client-SDKs. - Eine allgemeine Schnittstelle zum Ausführen beliebiger GraphQL-Vorgänge, in der Ihr Code Abfragen und Mutationen implementiert und an die Lese-/Schreibmethode
executeGraphqloder die schreibgeschützte MethodeexecuteGraphqlReadübergibt. - Eine spezielle Schnittstelle für Bulk-Datenvorgänge, die anstelle generischer
executeGraphql-Methoden spezielle Methoden für Mutationsvorgänge bereitstellt:insert,insertMany,upsertundupsertMany.
Daten mit generierten SDKs verwalten
Sie generieren Admin-SDKs aus Ihren gql-Definitionen auf dieselbe Weise wie Client-SDKs.
Das generierte Admin SDK enthält Schnittstellen und Funktionen, die Ihren gql-Definitionen entsprechen. Damit können Sie Vorgänge in Ihrer Datenbank ausführen. Angenommen, Sie haben ein SDK für eine Datenbank mit Songs zusammen mit einer Anfrage getSongs generiert:
import { initializeApp } from "firebase-admin/app";
import { getSongs } from "@dataconnect/admin-generated";
const adminApp = initializeApp();
const songs = await getSongs(
{ limit: 4 },
{ impersonate: { unauthenticated: true } }
);
So geben Sie eine Connector-Konfiguration an:
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 } }
);
Identität eines nicht authentifizierten Nutzers annehmen
Admin SDKs sind für die Ausführung in vertrauenswürdigen Umgebungen vorgesehen und haben daher uneingeschränkten Zugriff auf Ihre Datenbanken.
Wenn Sie öffentliche Vorgänge mit dem Admin SDK ausführen, sollten Sie vermeiden, den Vorgang mit vollständigen Administratorberechtigungen auszuführen (Prinzip der geringsten Berechtigung). Stattdessen sollten Sie den Vorgang entweder als imitierten Nutzer (siehe nächster Abschnitt) oder als imitierten nicht authentifizierten Nutzer ausführen.
Nicht authentifizierte Nutzer können nur Vorgänge ausführen, die mit PUBLIC gekennzeichnet sind.
Im Beispiel oben wird die Abfrage getSongs als nicht authentifizierter Nutzer ausgeführt.
Identitätsdiebstahl
Sie können auch Vorgänge im Namen bestimmter Nutzer ausführen, indem Sie einen Teil oder das gesamte Firebase Authentication-Token in der Option impersonate übergeben. Mindestens müssen Sie die Nutzer-ID des Nutzers im Anspruch „sub“ angeben. Dieser Wert entspricht dem auth.uid-Serverwert, auf den Sie in Data Connect GraphQL-Vorgängen verweisen können.
Wenn Sie einen Nutzer imitieren, ist der Vorgang nur erfolgreich, wenn die von Ihnen angegebenen Nutzerdaten die in Ihrer GraphQL-Definition angegebenen Authentifizierungsprüfungen bestehen.
Wenn Sie das generierte SDK über einen öffentlich zugänglichen Endpunkt aufrufen, ist es wichtig, dass für den Endpunkt eine Authentifizierung erforderlich ist und dass Sie die Integrität des Authentifizierungstokens validieren, bevor Sie es verwenden, um die Identität eines Nutzers anzunehmen.
Wenn Sie aufrufbare Cloud Functions verwenden, wird das Authentifizierungstoken automatisch überprüft. Sie können es wie im folgenden Beispiel verwenden:
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 } }
);
// ...
});
Andernfalls verwenden Sie die Methode verifyIdToken des Admin SDK, um das Authentifizierungstoken zu validieren und zu decodieren. Angenommen, Ihr Endpunkt ist als einfache HTTP-Funktion implementiert und Sie haben das Firebase Authentication-Token wie üblich mit dem authorization-Header an Ihren Endpunkt übergeben:
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 } }
);
// ...
});
Nur wenn Sie echte administrative Aufgaben wie die Datenmigration in einer sicheren, nicht öffentlich zugänglichen Umgebung ausführen, sollten Sie eine Nutzer-ID angeben, die nicht aus einer überprüfbaren Quelle stammt:
// Never do this if end users can initiate execution of the code!
const favoriteSongs = await getMyFavoriteSongs(
undefined,
{ impersonate: { authClaims } }
);
Mit uneingeschränktem Zugriff ausführen
Wenn Sie einen Vorgang ausführen, für den Berechtigungen auf Administratorebene erforderlich sind, lassen Sie den Parameter „impersonate“ im Aufruf weg:
await upsertSong(adminDc, {
title: songTitle_one,
instrumentsUsed: [Instrument.VOCAL],
});
Ein so aufgerufener Vorgang hat vollständigen Zugriff auf die Datenbank. Wenn Sie Abfragen oder Mutationen haben, die nur für Verwaltungszwecke verwendet werden sollen, sollten Sie sie mit der Direktive @auth(level: NO_ACCESS) definieren. So wird sichergestellt, dass nur Anrufer mit Administratorberechtigungen diese Vorgänge ausführen können.
Daten mit executeGraphql-Methoden verwalten
Wenn Sie einmalige Vorgänge ausführen müssen, für die Sie keine gql-Mutationen oder ‑Abfragen definiert haben, können Sie die Methode executeGraphql oder die schreibgeschützte Methode executeGraphqlRead verwenden.
Identität eines nicht authentifizierten Nutzers annehmen
Wenn Sie öffentliche Vorgänge mit dem Admin SDK ausführen, sollten Sie vermeiden, den Vorgang mit vollständigen Administratorberechtigungen auszuführen (Prinzip der geringsten Berechtigung). Stattdessen sollten Sie den Vorgang entweder als imitierten Nutzer (siehe nächster Abschnitt) oder als imitierten nicht authentifizierten Nutzer ausführen. Nicht authentifizierte Nutzer können nur Vorgänge ausführen, die mit PUBLIC gekennzeichnet sind.
// 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);
Identitätsdiebstahl
Es gibt auch Anwendungsfälle, in denen Sie möchten, dass Ihre Skripts Nutzerdaten im Namen eines bestimmten Nutzers auf Grundlage eingeschränkter Anmeldedaten ändern. Dieser Ansatz entspricht dem Prinzip der geringsten Berechtigung.
Um diese Schnittstelle zu verwenden, müssen Sie Informationen aus einem benutzerdefinierten JWT-Authentifizierungstoken abrufen, das dem Tokenformat Authentication entspricht. Weitere Informationen finden Sie im Leitfaden zu benutzerdefinierten Tokens.
// 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" } } }
Administratoranmeldedaten verwenden
Wenn Sie einen Vorgang ausführen, für den Berechtigungen auf Administratorebene erforderlich sind, lassen Sie den Parameter „impersonate“ im Aufruf weg:
// 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" } } }
Ein so aufgerufener Vorgang hat vollständigen Zugriff auf die Datenbank. Wenn Sie Abfragen oder Mutationen haben, die nur für Verwaltungszwecke verwendet werden sollen, sollten Sie sie mit der Direktive @auth(level: NO_ACCESS) definieren. So wird sichergestellt, dass nur Anrufer mit Administratorberechtigungen diese Vorgänge ausführen können.
Bulk-Datenvorgänge ausführen
Firebase empfiehlt die Verwendung von Admin SDK für Massendatenvorgänge in Produktionsdatenbanken.
Das SDK bietet die folgenden Methoden für die Arbeit mit Bulk-Daten. Aus den bereitgestellten Argumenten wird mit jeder Methode eine GraphQL-Mutation erstellt und ausgeführt.
// 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);
Hinweise zur Leistung bei Bulk-Vorgängen
Für jede Anfrage an das Backend ist ein Roundtrip zu Cloud SQL erforderlich. Je mehr Sie also in Batches zusammenfassen, desto höher ist der Durchsatz.
Je größer die Batchgröße ist, desto länger ist jedoch die generierte SQL-Anweisung. Wenn das Längenlimit für PostgreSQL-SQL-Anweisungen erreicht ist, tritt ein Fehler auf.
In der Praxis sollten Sie experimentieren, um die passende Batchgröße für Ihre Arbeitslast zu ermitteln.
Nächste Schritte
- Informationen zum Einfügen von Daten in Ihre Datenbanken mit dem Admin SDK
- Sehen Sie sich die API für Admin SDK an.
- Verwenden Sie die Firebase CLI und die Google Cloud-Konsole für andere Projektverwaltungsaufgaben, z. B. Schemas und Connectors verwalten und Dienste und Datenbanken verwalten.