El Firebase Admin SDK es un conjunto de bibliotecas de servidor que te permite interactuar con Firebase desde entornos con privilegios para realizar acciones como ejecutar consultas y mutaciones en un Firebase Data Connect servicio para la administración de datos masivos y otras operaciones con privilegios elevados y credenciales suplantadas.
El Admin SDK te proporciona una API para llamar a operaciones en modos de lectura/escritura y de solo lectura. Con las operaciones de solo lectura, tienes la tranquilidad de implementar funciones administrativas que no pueden modificar los datos en tus bases de datos.
Configuración del SDK de Admin
Para comenzar a usar el con Firebase Data Connect en tu servidor, primero deberás instalar y configurar el Admin SDK para Node.js.
Inicializa el SDK de Admin en tus secuencias de comandos
Para inicializar el SDK, importa las extensiones Data Connect y declara el ID y la ubicación del servicio de tu proyecto.
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'
});
Diseña consultas y mutaciones para usar con el Admin SDK
El Admin SDK es útil para ejecutar Data Connect operaciones, dadas las siguientes consideraciones.
Comprende el SDK y la directiva de operación @auth(level: NO_ACCESS)
Dado que el Admin SDK opera con privilegios, puede ejecutar cualquiera de tus
consultas y mutaciones, independientemente de los niveles de acceso establecidos con las directivas @auth, incluido el nivel NO_ACCESS.
Si, junto con las operaciones del cliente, organizas tus consultas y mutaciones administrativas en archivos fuente .gql para importarlas a secuencias de comandos administrativas, Firebase recomienda que marques las operaciones administrativas sin ningún nivel de acceso de autorización o que seas más explícito y las establezcas como NO_ACCESS. De cualquier manera, esto evita que esas operaciones se ejecuten desde clientes o en otros contextos no privilegiados.
Usa el SDK con el emulador Data Connect
En los entornos de prototipos y pruebas, puede ser útil realizar la propagación de datos y otras operaciones en datos locales. El Admin SDK te permite simplificar tus flujos de trabajo, ya que puede ignorar la autenticación y la autorización para los flujos locales. (También puedes habilitar de forma explícita el cumplimiento de la configuración de autenticación y autorización de tus operaciones con la identidad temporal de usuarios).
Los SDK de Firebase Admin se conectan automáticamente al Data Connect
emulador cuando se configura la variable de entorno DATA_CONNECT_EMULATOR_HOST de la siguiente manera:
export DATA_CONNECT_EMULATOR_HOST="127.0.0.1:9399"
Para obtener más información, consulte:
- La guía para la propagación de datos en el desarrollo local
- La documentación del emulador Data Connect.
Ejecuta operaciones de administrador
El Admin SDK se proporciona para operaciones con privilegios en tus datos críticos.
El SDK de Admin proporciona tres conjuntos de APIs:
- SDKs de Admin generados, que son SDKs con seguridad de tipos generados a partir de tus definiciones
gqlde la misma manera que generas SDKs de cliente - Una interfaz general para ejecutar operaciones de GraphQL arbitrarias, en la que tu
código implementa consultas y mutaciones, y las pasa al método de lectura y escritura
executeGraphqlo al método de solo lecturaexecuteGraphqlRead - Una interfaz especializada para operaciones de datos masivas que, en lugar de
métodos
executeGraphqlgenéricos, expone métodos dedicados para operaciones de mutación:insert,insertMany,upsertyupsertMany.
Administra datos con SDKs generados
Generas SDKs de Admin a partir de tus gql definiciones
de la misma manera que generas SDKs de cliente.
El SDK de Admin generado contiene interfaces y funciones que corresponden a tus definiciones gql, que puedes usar para realizar operaciones en tu base de datos. Por ejemplo, supongamos que generaste un SDK para una base de datos de canciones, junto con una consulta, 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 } }
);
O bien, para especificar una configuración de conector:
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 } }
);
Suplantación de un usuario no autenticado
Los SDKs de Admin están diseñados para ejecutarse desde entornos de confianza y, por lo tanto, tienen acceso sin restricciones a tus bases de datos.
Cuando ejecutas operaciones públicas con el SDK de Admin, debes evitar ejecutar la operación con privilegios de administrador completos (siguiendo el principio de privilegio mínimo). En su lugar, debes ejecutar la operación como un usuario suplantado (consulta la siguiente sección) o como un usuario no autenticado suplantado.
Los usuarios no autenticados solo pueden ejecutar operaciones marcadas como PUBLIC.
En el ejemplo anterior, la consulta getSongs se ejecuta como un usuario no autenticado.
Suplantación de un usuario
También puedes realizar operaciones en nombre de usuarios específicos pasando parte o
la totalidad de un token Firebase Authentication en la opción impersonate. Como mínimo, debes especificar el ID de usuario del usuario en la declaración sub. (Este es el mismo valor que el
auth.uid valor del servidor
al que puedes hacer referencia en Data Connect operaciones de GraphQL).
Cuando suplantas a un usuario, la operación solo se realizará correctamente si los datos del usuario que proporcionaste pasan las verificaciones de autenticación especificadas en tu definición de GraphQL.
Si llamas al SDK generado desde un extremo accesible de forma pública, es fundamental que el extremo requiera autenticación y que valides la integridad del token de autenticación antes de usarlo para suplantar a un usuario.
Cuando usas invocables Cloud Functions, el token de autenticación se verifica automáticamente y puedes usarlo como en el siguiente ejemplo:
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 } }
);
// ...
});
De lo contrario, usa el Admin SDK del verifyIdToken para validar y decodificar
el token de autenticación. Por ejemplo, supongamos que tu extremo se implementa como una
función HTTP simple y que pasaste el Firebase Authentication token
a tu extremo con el authorization encabezado, como es estándar:
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 } }
);
// ...
});
Solo cuando realices tareas administrativas verdaderas, como la migración de datos, desde un entorno seguro y no accesible de forma pública, debes especificar un ID de usuario que no provenga de una fuente verificable:
// Never do this if end users can initiate execution of the code!
const favoriteSongs = await getMyFavoriteSongs(
undefined,
{ impersonate: { authClaims } }
);
Ejecución con acceso sin restricciones
Si realizas una operación que requiere permisos de nivel de administrador, omite el parámetro de suplantación de la llamada:
await upsertSong(adminDc, {
title: songTitle_one,
instrumentsUsed: [Instrument.VOCAL],
});
Una operación llamada de esta manera tiene acceso completo a la base de datos. Si tienes consultas o mutaciones que solo se usarán con fines de administración, debes definirlas con la directiva @auth(level: NO_ACCESS). De esta manera, se garantiza que solo los emisores de nivel de administrador puedan ejecutar estas operaciones.
Administra datos con métodos executeGraphql
Si necesitas ejecutar operaciones únicas para las que no definiste gql
mutaciones o consultas, puedes usar el método executeGraphql o el método
executeGraphqlRead de solo lectura.
Suplantación de un usuario no autenticado
Cuando ejecutas operaciones públicas con el SDK de Admin, debes evitar ejecutar la operación con privilegios de administrador completos (siguiendo el principio de privilegio mínimo). En su lugar, debes ejecutar la operación como un usuario suplantado
(consulta la siguiente sección) o como un usuario no autenticado
suplantado. Los usuarios no autenticados solo pueden ejecutar operaciones marcadas como 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);
Suplantación de un usuario
También hay casos de uso en los que deseas que tus secuencias de comandos modifiquen los datos del usuario en función de credenciales limitadas, en nombre de un usuario específico. Este enfoque respeta el principio de privilegio mínimo.
Para usar esta interfaz, recopila información de un token de autenticación JWT personalizado que siga el formato de token Authentication. Consulta también la guía de tokens personalizados.
// 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" } } }
Usa credenciales administrativas
Si realizas una operación que requiere permisos de nivel de administrador, omite el parámetro de suplantación de la llamada:
// 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" } } }
Una operación llamada de esta manera tiene acceso completo a la base de datos. Si tienes consultas o mutaciones que solo se usarán con fines de administración, debes definirlas con la directiva @auth(level: NO_ACCESS). De esta manera, se garantiza que solo los emisores de nivel de administrador puedan ejecutar estas operaciones.
Realiza operaciones de datos masivas
Firebase recomienda usar el Admin SDK para operaciones de datos masivas en bases de datos de producción.
El SDK proporciona los siguientes métodos para trabajar con datos masivos. A partir de los argumentos proporcionados, cada método construye y ejecuta una mutación de 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);
Notas de rendimiento para operaciones masivas
Cada solicitud al backend generará un viaje de ida y vuelta a Cloud SQL, por lo que, cuanto más agrupes, mayor será el rendimiento.
Sin embargo, cuanto más grande sea el tamaño del lote, más larga será la sentencia de SQL generada. Cuando se alcance el límite de longitud de la sentencia de SQL de PostgreSQL, se producirá un error.
En la práctica, experimenta para encontrar el tamaño de lote adecuado para tu carga de trabajo.
Próximos pasos
- Obtén información para propagar tus bases de datos con datos usando el Admin SDK
- Revisa la API del Admin SDK.
- Usa la Firebase CLI y la Google Cloud consola para otras operaciones de administración de proyectos, como administrar esquemas y conectores y administrar servicios y bases de datos.