Firebase Admin SDK, सर्वर लाइब्रेरी का एक सेट है. इसकी मदद से, खास एनवायरमेंट से Firebase के साथ इंटरैक्ट किया जा सकता है. इससे कई कार्रवाइयाँ की जा सकती हैं. जैसे, Firebase SQL Connect सेवा पर क्वेरी और म्यूटेशन करना, बड़े पैमाने पर डेटा मैनेज करना, और खास सुविधाओं का ऐक्सेस और नकली क्रेडेंशियल के साथ अन्य कार्रवाइयाँ करना.
Admin SDK आपको एक एपीआई उपलब्ध कराता है. इसकी मदद से, रीड/राइट और रीड-ओनली मोड, दोनों में कार्रवाइयां की जा सकती हैं. सिर्फ़ पढ़ने की अनुमति वाली कार्रवाइयों से, आपको एडमिन से जुड़े ऐसे फ़ंक्शन लागू करने में मदद मिलती है जिनसे आपके डेटाबेस में मौजूद डेटा में बदलाव नहीं किया जा सकता.
Admin SDK सेटअप करना
अपने सर्वर पर Firebase SQL Connect का इस्तेमाल शुरू करने के लिए, आपको सबसे पहले Node.js के लिए Admin SDK को इंस्टॉल और सेट अप करना होगा.
अपनी स्क्रिप्ट में Admin SDK टूल को शुरू करना
SDK टूल को शुरू करने के लिए, SQL Connect एक्सटेंशन इंपोर्ट करें. साथ ही, अपने प्रोजेक्ट का सर्विस आईडी और जगह की जानकारी डालें.
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'
});
Admin SDK के साथ इस्तेमाल करने के लिए क्वेरी और म्यूटेशन डिज़ाइन करना
SQL Connect कार्रवाइयां करने के लिए, Admin SDK का इस्तेमाल किया जा सकता है. हालांकि, इसके लिए इन बातों का ध्यान रखना ज़रूरी है.
एसडीके और @auth(level: NO_ACCESS) ऑपरेशन डायरेक्टिव को समझना
Admin SDK के पास खास अधिकार होते हैं. इसलिए, यह आपकी किसी भी क्वेरी और म्यूटेशन को लागू कर सकता है. भले ही, @auth डायरेक्टिव का इस्तेमाल करके सेट किए गए ऐक्सेस लेवल कुछ भी हों. इसमें NO_ACCESS लेवल भी शामिल है.
अगर क्लाइंट के ऑपरेशंस के साथ-साथ, एडमिन से जुड़ी क्वेरी और म्यूटेशन को .gql सोर्स फ़ाइलों में व्यवस्थित किया जाता है, ताकि उन्हें एडमिन स्क्रिप्ट में इंपोर्ट किया जा सके, तो Firebase का सुझाव है कि एडमिन से जुड़े ऑपरेशंस को बिना किसी अनुमति के ऐक्सेस लेवल के तौर पर मार्क करें. इसके अलावा, उन्हें NO_ACCESS के तौर पर सेट किया जा सकता है. इन दोनों ही तरीकों से, इस तरह की कार्रवाइयों को क्लाइंट या अन्य गैर-ज़रूरी कॉन्टेक्स्ट से लागू होने से रोका जाता है.
SQL Connect एम्युलेटर के साथ एसडीके का इस्तेमाल करना
प्रोटोटाइप और टेस्ट एनवायरमेंट में, लोकल डेटा पर डेटा सीडिंग और अन्य कार्रवाइयां करना फ़ायदेमंद हो सकता है. Admin SDK की मदद से, अपने वर्कफ़्लो को आसान बनाया जा सकता है. ऐसा इसलिए, क्योंकि यह लोकल फ़्लो के लिए पुष्टि करने और अनुमति देने की प्रोसेस को अनदेखा कर सकता है. (आपके पास, उपयोगकर्ता की पहचान चुराकर की जाने वाली कार्रवाइयों के लिए, पुष्टि करने और अनुमति देने से जुड़ी सेटिंग का पालन करने का विकल्प भी होता है.)
Firebase Admin SDK टूल, SQL Connect एनवायरमेंट वैरिएबल सेट होने पर, SQL Connect एम्युलेटर से अपने-आप कनेक्ट हो जाता है:DATA_CONNECT_EMULATOR_HOST
export DATA_CONNECT_EMULATOR_HOST="127.0.0.1:9399"
ज़्यादा जानकारी के लिए, ये देखें:
- लोकल डेवलपमेंट में डेटा सीडिंग के लिए गाइड
- SQL Connect एम्युलेटर के बारे में जानकारी देने वाला दस्तावेज़.
एडमिन से जुड़ी कार्रवाइयां करना
Admin SDK, आपके अहम डेटा पर खास कार्रवाइयां करने के लिए उपलब्ध कराया जाता है.
एडमिन एसडीके, एपीआई के तीन सेट उपलब्ध कराता है:
- जनरेट किए गए एडमिन SDK टूल. ये टाइप-सेफ़ SDK टूल होते हैं. इन्हें आपकी
gqlडेफ़िनिशन से जनरेट किया जाता है. इन्हें उसी तरह जनरेट किया जाता है जिस तरह क्लाइंट SDK टूल जनरेट किए जाते हैं. - यह GraphQL की किसी भी कार्रवाई को चलाने के लिए एक सामान्य इंटरफ़ेस है. इसमें आपका कोड, क्वेरी और म्यूटेशन लागू करता है और उन्हें read-write
executeGraphqlतरीके या read-onlyexecuteGraphqlReadतरीके को पास करता है. - बल्क डेटा ऑपरेशन के लिए एक खास इंटरफ़ेस. यह सामान्य
executeGraphqlतरीकों के बजाय, म्यूटेशन ऑपरेशन के लिए खास तरीके दिखाता है:insert,insertMany,upsert, औरupsertMany.
जनरेट किए गए एसडीके की मदद से डेटा मैनेज करना
क्लाइंट एसडीके जनरेट करने के तरीके से ही, gql की परिभाषाओं से एडमिन एसडीके जनरेट किए जाते हैं.
जनरेट किए गए एडमिन एसडीके में ऐसे इंटरफ़ेस और फ़ंक्शन होते हैं जो आपकी gql परिभाषाओं से मेल खाते हैं. इनका इस्तेमाल करके, अपने डेटाबेस पर कार्रवाइयां की जा सकती हैं. उदाहरण के लिए, मान लें कि आपने गानों के डेटाबेस के लिए एक एसडीके जनरेट किया है. साथ ही, आपने एक क्वेरी भी जनरेट की है, 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 } }
);
इसके अलावा, कनेक्टर कॉन्फ़िगरेशन के बारे में बताने के लिए:
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 } }
);
बिना पुष्टि किए गए उपयोगकर्ता के तौर पर काम करना
Admin SDK को भरोसेमंद एनवायरमेंट से चलाने के लिए डिज़ाइन किया गया है. इसलिए, इनके पास आपके डेटाबेस का पूरा ऐक्सेस होता है.
एडमिन SDK की मदद से सार्वजनिक कार्रवाइयां करते समय, आपको एडमिन के सभी अधिकारों के साथ कार्रवाई नहीं करनी चाहिए. इसके लिए, कम से कम ज़रूरी अधिकारों के सिद्धांत का पालन करें. इसके बजाय, आपको इस ऑपरेशन को किसी ऐसे उपयोगकर्ता के तौर पर चलाना चाहिए जिसके पास उपयोगकर्ता के तौर पर काम करने की अनुमति हो (अगला सेक्शन देखें) या ऐसे उपयोगकर्ता के तौर पर चलाना चाहिए जिसके पास पुष्टि किए गए उपयोगकर्ता के तौर पर काम करने की अनुमति न हो.
पुष्टि न किए गए उपयोगकर्ता, सिर्फ़ PUBLIC के तौर पर मार्क किए गए ऑपरेशन चला सकते हैं.
ऊपर दिए गए उदाहरण में, getSongs क्वेरी को बिना पुष्टि किए उपयोगकर्ता के तौर पर लागू किया गया है.
किसी उपयोगकर्ता की पहचान चुराकर कार्रवाई करना
impersonate विकल्प में Firebase Authentication टोकन का कुछ हिस्सा या पूरा टोकन पास करके, चुनिंदा उपयोगकर्ताओं की ओर से भी कार्रवाइयां की जा सकती हैं. कम से कम, आपको सब-क्लेम में उपयोगकर्ता का यूज़र आईडी देना होगा. (यह वही वैल्यू है जो auth.uid सर्वर वैल्यू है. इसे SQL Connect GraphQL ऑपरेशंस में रेफ़रंस किया जा सकता है.)
किसी उपयोगकर्ता के तौर पर काम करने पर, कार्रवाई सिर्फ़ तब पूरी होगी, जब आपके दिए गए उपयोगकर्ता डेटा की पुष्टि हो जाए. इसके लिए, GraphQL की परिभाषा में बताई गई पुष्टि की जांच की जाती है.
अगर जनरेट किए गए SDK को सार्वजनिक तौर पर ऐक्सेस किए जा सकने वाले एंडपॉइंट से कॉल किया जा रहा है, तो यह ज़रूरी है कि एंडपॉइंट के लिए पुष्टि करना ज़रूरी हो. साथ ही, किसी उपयोगकर्ता के तौर पर काम करने के लिए, पुष्टि करने वाले टोकन का इस्तेमाल करने से पहले, आपको उसकी पुष्टि करनी होगी.
कॉल किए जा सकने वाले Cloud Functions का इस्तेमाल करते समय, पुष्टि करने वाले टोकन की पुष्टि अपने-आप हो जाती है. इसका इस्तेमाल इस उदाहरण की तरह किया जा सकता है:
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 } }
);
// ...
});
इसके अलावा, पुष्टि करने वाले टोकन की पुष्टि करने और उसे डिकोड करने के लिए, Admin SDK के verifyIdToken तरीके का इस्तेमाल करें. उदाहरण के लिए, मान लें कि आपका एंडपॉइंट, सामान्य एचटीटीपी फ़ंक्शन के तौर पर लागू किया गया है और आपने authorization हेडर का इस्तेमाल करके, अपने एंडपॉइंट को Firebase Authentication टोकन पास किया है. यह स्टैंडर्ड तरीका है:
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 } }
);
// ...
});
आपको सिर्फ़ तब ऐसे यूज़र आईडी का इस्तेमाल करना चाहिए जो पुष्टि किए जा सकने वाले सोर्स से नहीं मिला है, जब आपको एडमिन से जुड़े काम करने हों. जैसे, सुरक्षित और सार्वजनिक तौर पर ऐक्सेस न किए जा सकने वाले एनवायरमेंट से डेटा माइग्रेट करना:
// Never do this if end users can initiate execution of the code!
const favoriteSongs = await getMyFavoriteSongs(
undefined,
{ impersonate: { authClaims } }
);
बिना पाबंदी वाले ऐक्सेस के साथ चल रहा है
अगर आपको ऐसा ऑपरेशन करना है जिसके लिए एडमिन लेवल की अनुमतियों की ज़रूरत होती है, तो कॉल से impersonate पैरामीटर हटाएं:
await upsertSong(adminDc, {
title: songTitle_one,
instrumentsUsed: [Instrument.VOCAL],
});
इस तरह से कॉल की गई किसी कार्रवाई के पास डेटाबेस का पूरा ऐक्सेस होता है. अगर आपको सिर्फ़ एडमिन के कामों के लिए क्वेरी या म्यूटेशन का इस्तेमाल करना है, तो आपको उन्हें @auth(level: NO_ACCESS) डायरेक्टिव के साथ तय करना चाहिए. ऐसा करने से, यह पक्का किया जा सकता है कि सिर्फ़ एडमिन-लेवल के कॉलर ही इन कार्रवाइयों को पूरा कर सकें.
executeGraphql तरीकों से डेटा मैनेज करना
अगर आपको एक बार की जाने वाली ऐसी कार्रवाइयां करनी हैं जिनके लिए आपने gql
म्यूटेशन या क्वेरी तय नहीं की हैं, तो executeGraphql या सिर्फ़ पढ़ने के लिए executeGraphqlRead तरीके का इस्तेमाल किया जा सकता है.
executeGraphql का इस्तेमाल करके, कस्टम नेस्टेड रिलेशनल ऑपरेशन (एक से ज़्यादा और एक से एक) करना
ज़्यादा सुविधाओं वाले एनवायरमेंट में Admin SDK से कार्रवाइयां कॉल करते समय, आपको स्टैंडर्ड फ़्लैट (नॉन-नेस्टेड) इंसर्शन के लिए, अपने वैरिएबल पर @allow डायरेक्टिव तय करने की ज़रूरत नहीं होती. जैसे, अलग-अलग फ़िल्म या अभिनेता के रिकॉर्ड इंसर्ट करना.
हालांकि, नेस्ट किए गए रिलेशनल इंसर्ट (जैसे कि किसी फ़िल्म को उसकी शुरुआती समीक्षाओं या किसी उपयोगकर्ता और उसकी प्रोफ़ाइल के साथ इंसर्ट करना) के लिए, आपको अब भी अपने वैरिएबल की परिभाषा पर @allow डायरेक्टिव का एलान करना होगा. इससे, कंपाइल किए गए वैरिएबल स्कीमा में नेस्ट किए गए रिलेशनल फ़ील्ड को स्टैटिक तौर पर अनुमति दी जा सकेगी.
// Custom GraphQL mutation with nested relational insert (one-to-many)
const customMutation = `
mutation CustomBatchInsert(
$data: [Movie_Data!]!
@allow(fields: "title genre reviews_on_movie { rating reviewText }")
) {
movie_insertMany(data: $data)
}
`;
const variables = {
data: [
{
title: "Interstellar",
genre: "Sci-Fi",
reviews_on_movie: [
{
rating: 5,
reviewText: "Visually stunning and emotionally powerful.",
user: { id: "user-789" }
}
]
}
]
};
const response = await dataConnect.executeGraphql(customMutation, { variables });
// Custom GraphQL mutation with a one-to-one nested relational insert
const customMutationOneToOne = `
mutation CustomBatchInsertOneToOne(
$data: [User_Data!]!
@allow(fields: "name profile_on_user { bio }")
) {
user_insertMany(data: $data)
}
`;
const variablesOneToOne = {
data: [
{
name: "Alice",
profile_on_user: {
bio: "Avid moviegoer and critic."
}
}
]
};
const responseOneToOne = await dataConnect.executeGraphql(customMutationOneToOne, { variables: variablesOneToOne });
बिना पुष्टि किए गए उपयोगकर्ता के तौर पर काम करना
एडमिन SDK की मदद से सार्वजनिक कार्रवाइयां करते समय, आपको एडमिन के सभी अधिकारों के साथ कार्रवाई नहीं करनी चाहिए. इसके लिए, कम से कम ज़रूरी अधिकारों के सिद्धांत का पालन करें. इसके बजाय, आपको कार्रवाई को किसी ऐसे उपयोगकर्ता के तौर पर चलाना चाहिए जिसकी पहचान की पुष्टि नहीं हुई है. इसके लिए, अगला सेक्शन देखें. पुष्टि न किए गए उपयोगकर्ता, सिर्फ़ 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);
किसी उपयोगकर्ता की पहचान चुराकर कार्रवाई करना
ऐसे भी इस्तेमाल के उदाहरण हैं जहां आपको किसी खास उपयोगकर्ता की ओर से, सीमित क्रेडेंशियल के आधार पर उपयोगकर्ता के डेटा में बदलाव करने के लिए अपनी स्क्रिप्ट का इस्तेमाल करना होता है. इस तरीके में, कम से कम अधिकारों के सिद्धांत का पालन किया जाता है.
इस इंटरफ़ेस का इस्तेमाल करने के लिए, Authentication टोकन फ़ॉर्मैट के मुताबिक बनाए गए, ज़रूरत के हिसाब से बनाए गए JWT ऑथराइज़ेशन टोकन से जानकारी इकट्ठा करें. कस्टम टोकन के बारे में जानकारी भी देखें.
// 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" } } }
एडमिन क्रेडेंशियल का इस्तेमाल करना
अगर आपको ऐसा ऑपरेशन करना है जिसके लिए एडमिन लेवल की अनुमतियों की ज़रूरत होती है, तो कॉल से impersonate पैरामीटर हटाएं:
// 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" } } }
इस तरह से कॉल की गई किसी कार्रवाई के पास डेटाबेस का पूरा ऐक्सेस होता है. अगर आपको सिर्फ़ एडमिन के कामों के लिए क्वेरी या म्यूटेशन का इस्तेमाल करना है, तो आपको उन्हें @auth(level: NO_ACCESS) डायरेक्टिव के साथ तय करना चाहिए. ऐसा करने से, यह पक्का किया जा सकता है कि सिर्फ़ एडमिन-लेवल के कॉलर ही इन कार्रवाइयों को पूरा कर सकें.
एक साथ कई डेटा डालने की कार्रवाइयां करना
Firebase का सुझाव है कि प्रोडक्शन डेटाबेस पर डेटा से जुड़ी कई कार्रवाइयां करने के लिए, Admin SDK का इस्तेमाल करें.
एसडीके, एक साथ कई डेटा आइटम पर काम करने के लिए ये तरीके उपलब्ध कराता है. दिए गए आर्ग्युमेंट से, हर तरीके में एक GraphQL म्यूटेशन बनाया और उसे लागू किया जाता है.
// Methods of the bulk operations API
// dc is a SQL 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);
नेस्टेड रिलेशनल ऑपरेशन (वन-टू-मेनी और वन-टू-वन)
Admin SDK, बल्क ऑपरेशन में रिलेशनल डेटा के साथ काम करता है. कस्टम म्यूटेशन की तरह ही, वन-टू-मेनी रिलेशनशिप के लिए ऑब्जेक्ट की एक कैटगरी और वन-टू-वन रिलेशनशिप के लिए एक ऑब्जेक्ट का इस्तेमाल करें:
// Example of inserting a movie with nested reviews (one-to-many)
const moviesData = [
{
title: "Interstellar",
genre: "Sci-Fi",
reviews_on_movie: [
{
rating: 5,
reviewText: "Visually stunning and emotionally powerful.",
user: { id: "user-789" }
}
]
}
];
// Atomically insert movies and their reviews in a single database round-trip.
const response = await dc.insertMany("movie", moviesData);
// Example of inserting a user with a nested profile (one-to-one)
const usersData = [
{
name: "Alice",
profile_on_user: {
bio: "Avid moviegoer and critic."
}
}
];
// Atomically insert users and their profiles.
const userResponse = await dc.insertMany("user", usersData);
बल्क ऑपरेशन के लिए परफ़ॉर्मेंस से जुड़ी ज़रूरी बातें
बैकएंड को किए गए हर अनुरोध के लिए, Cloud SQL को एक राउंड ट्रिप करनी होगी. इसलिए, बैच में जितने ज़्यादा अनुरोध किए जाएंगे, थ्रूपुट उतना ही ज़्यादा होगा.
हालांकि, बैच का साइज़ जितना बड़ा होगा, जनरेट किया गया एसक्यूएल स्टेटमेंट उतना ही लंबा होगा. जब PostgreSQL एसक्यूएल स्टेटमेंट की लंबाई की सीमा पूरी हो जाती है, तो आपको एक गड़बड़ी दिखेगी.
अपने वर्कलोड के लिए सही बैच का साइज़ पता लगाने के लिए, एक्सपेरिमेंट करें.
आगे क्या करना है?
- Admin SDK का इस्तेमाल करके, अपने डेटाबेस में डेटा जोड़ने के बारे में जानें
- Admin SDK के लिए एपीआई देखें.
- Firebase सीएलआई और Google Cloud कंसोल का इस्तेमाल, प्रोजेक्ट मैनेजमेंट से जुड़ी अन्य कार्रवाइयों के लिए करें. जैसे, स्कीमा और कनेक्टर मैनेज करना और सेवाएं और डेटाबेस मैनेज करना.