Admin Node SDK
Consult this file when writing server-side code (e.g., Cloud Functions) that needs elevated privileges or needs to impersonate specific users.
Best Practices for Agents
- Understand Operation Storage: SQL Connect queries and mutations are stored on the server like Cloud Functions. Clients do not submit the raw operations. Therefore, whenever you update operations, you must regenerate the SDK and redeploy services that use it.
- Follow Least Privilege: Admin SDKs have unrestricted access by default. Always use impersonation when possible to limit access.
- Impersonation: Use the
impersonateparameter to run operations as a specific user or as an unauthenticated user. - Impersonation Variables: If you call an operation with optional variables
and want to pass impersonation options but without variables, you MUST
pass
undefinedas the first argument (variables) to clearly indicate no variables are being provided. - Admin Operations: If you create operations intended only for
administration, define them with
@auth(level: NO_ACCESS). This ensures they can only be called via the Admin SDK with unrestricted access. - Resilient Enum Handling: JavaScript/TypeScript does not enforce exhaustive
checks on enums. Always add a
defaultbranch toswitchstatements or anelsebranch to handle unknown values gracefully when schemas evolve.
Configuration in connector.yaml
To generate an Admin SDK, add the adminNodeSdk block to your connector.yaml:
connectorId: my-connector
generate:
adminNodeSdk:
outputDir: "./admin-sdk"
package: "@dataconnect/admin-generated"
packageJsonDir: "." # Directory containing package.jsonGeneration
Run the generation command:
npx -y firebase-tools@latest dataconnect:sdk:generateUsage Examples
1. Impersonating an Unauthenticated User
Unauthenticated users can only run operations marked as PUBLIC.
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 } }
);2. Impersonating a Specific User (Cloud Functions)
When using callable Cloud Functions, the authentication token is automatically verified.
import { HttpsError, onCall } from "firebase-functions/https";
import { getMyFavoriteSongs } from "@dataconnect/admin-generated";
export const callableExample = onCall(async (req) => {
const authClaims = req.auth?.token;
if (!authClaims) {
throw new HttpsError("unauthenticated", "Unauthorized");
}
const favoriteSongs = await getMyFavoriteSongs(
adminDc,
undefined,
{ impersonate: { authClaims } }
);
return favoriteSongs;
});3. Impersonating a Specific User (Plain HTTP)
For non-callable endpoints, you must verify the token yourself.
import { getAuth } from "firebase-admin/auth";
import { onRequest } from "firebase-functions/https";
import { getMyFavoriteSongs } from "@dataconnect/admin-generated";
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(
adminDc,
undefined,
{ impersonate: { authClaims } }
);
res.send(favoriteSongs);
});4. Running with Unrestricted Access
Omit the impersonate parameter to run with full admin access. Only do this for
true administrative tasks.
import { upsertSong } from "@dataconnect/admin-generated";
await upsertSong(adminDc, {
title: "New Song",
genre: "Rock"
});