מבוא ל-Admin Database SDK

בעזרת ה-SDK לאדמינים, אתם יכולים לקרוא ולכתוב נתונים ב-מסד נתונים בזמן אמת עם הרשאות אדמין מלאות, או עם הרשאות מוגבלות ומפורטות יותר. במסמך הזה נסביר איך להוסיף לפרויקט את ה-SDK של Firebase לאדמינים כדי לגשת אל Firebase Realtime Database.

הגדרת SDK לאדמינים

כדי להתחיל להשתמש במסד נתונים בזמן אמת ב-Firebase בשרת, קודם צריך להגדיר את Firebase Admin SDK בשפה הרצויה.

אימות SDK לאדמינים

כדי לגשת אל Firebase Realtime Database משרת באמצעות ה-SDK של Firebase לאדמינים, צריך לאמת את השרת ב-Firebase. כשמאמתים שרת, במקום להיכנס באמצעות פרטי הכניסה של חשבון משתמש כמו באפליקציית לקוח, מאמתים באמצעות חשבון שירות שמזהה את השרת ב-Firebase.

כשמבצעים אימות באמצעות ה-SDK של Firebase לאדמינים, אפשר לקבל שתי רמות גישה שונות:

רמות גישה לאימות ב-SDK של Firebase לאדמינים
הרשאות אדמין גישה מלאה לקריאה ולכתיבה של Realtime Database בפרויקט. השתמשו בו בזהירות כדי להשלים משימות ניהוליות כמו העברת נתונים או ארגון מחדש, שדורשות גישה בלתי מוגבלת למשאבי הפרויקט.
הרשאות מוגבלות גישה ל-Realtime Database של הפרויקט, שמוגבלת רק למשאבים שהשרת צריך. השתמשו ברמה הזו כדי להשלים משימות ניהוליות עם דרישות גישה מוגדרות היטב. לדוגמה, כשמריצים משימת סיכום שקוראת נתונים מכל מסד הנתונים, אפשר להגן מפני כתיבה מקרית על ידי הגדרת כלל אבטחה לקריאה בלבד, ואז להפעיל את SDK לאדמינים עם הרשאות שמוגבלות על ידי הכלל הזה.

אימות באמצעות הרשאות אדמין

כשמאתחלים את ה-SDK של Firebase לאדמינים עם פרטי הכניסה של חשבון שירות עם התפקיד עריכה בפרויקט Firebase, למכונה הזו יש גישה מלאה לקריאה ולכתיבה ב-Realtime Database של הפרויקט.

Java
// Initialize the SDK with Application Default Credentials
FirebaseOptions options = FirebaseOptions.builder()
    .setCredentials(GoogleCredentials.getApplicationDefault())
    // The database URL depends on the location of the database
    .setDatabaseUrl("https://DATABASE_NAME.firebaseio.com")
    .build();
FirebaseApp.initializeApp(options);

// As an admin, the app has access to read and write all data, regardless of Security Rules
DatabaseReference ref = FirebaseDatabase.getInstance()
    .getReference("restricted_access/secret_document");
ref.addListenerForSingleValueEvent(new ValueEventListener() {
  @Override
  public void onDataChange(DataSnapshot dataSnapshot) {
    Object document = dataSnapshot.getValue();
    System.out.println(document);
  }

  @Override
  public void onCancelled(DatabaseError error) {
  }
});
Node.js
import { initializeApp } from 'firebase-admin/app';
import { getDatabase } from 'firebase-admin/database';

// Initialize the app with Application Default Credentials, granting admin privileges
initializeApp({
  // The database URL depends on the location of the database
  databaseURL: "https://DATABASE_NAME.firebaseio.com"
});

// As an admin, the app has access to read and write all data, regardless of Security Rules
const db = getDatabase();
const ref = db.ref("restricted_access/secret_document");
ref.once("value", (snapshot) => {
  console.log(snapshot.val());
});
Python
import firebase_admin
from firebase_admin import credentials
from firebase_admin import db

# Fetch the service account key JSON file contents
cred = credentials.Certificate('path/to/serviceAccountKey.json')

# Initialize the app with a service account, granting admin privileges
firebase_admin.initialize_app(cred, {
    'databaseURL': 'https://databaseName.firebaseio.com'
})

# As an admin, the app has access to read and write all data, regradless of Security Rules
ref = db.reference('restricted_access/secret_document')
print(ref.get())
המשך
ctx := context.Background()
conf := &firebase.Config{
	DatabaseURL: "https://databaseName.firebaseio.com",
}
// Fetch the service account key JSON file contents
opt := option.WithCredentialsFile("path/to/serviceAccountKey.json")

// Initialize the app with a service account, granting admin privileges
app, err := firebase.NewApp(ctx, conf, opt)
if err != nil {
	log.Fatalln("Error initializing app:", err)
}

client, err := app.Database(ctx)
if err != nil {
	log.Fatalln("Error initializing database client:", err)
}

// As an admin, the app has access to read and write all data, regradless of Security Rules
ref := client.NewRef("restricted_access/secret_document")
var data map[string]interface{}
if err := ref.Get(ctx, &data); err != nil {
	log.Fatalln("Error reading from database:", err)
}
fmt.Println(data)

אימות עם הרשאות מוגבלות

השיטה המומלצת היא לתת לשירות גישה רק למשאבים שהוא צריך. כדי לקבל שליטה מדויקת יותר על המשאבים שמופע של אפליקציית Firebase יכול לגשת אליהם, צריך להשתמש במזהה ייחודי בכללי האבטחה כדי לייצג את השירות. לאחר מכן מגדירים כללים מתאימים שנותנים לשירות גישה למשאבים שהוא צריך. לדוגמה:

{
  "rules": {
    "public_resource": {
      ".read": true,
      ".write": true
    },
    "some_resource": {
      ".read": "auth.uid === 'my-service-worker'",
      ".write": false
    },
    "another_resource": {
      ".read": "auth.uid === 'my-service-worker'",
      ".write": "auth.uid === 'my-service-worker'"
    }
  }
}

לאחר מכן, בשרת, כשמפעילים את אפליקציית Firebase, משתמשים באפשרות databaseAuthVariableOverride כדי לשנות את האובייקט auth שבו משתמשים כללי מסד הנתונים. באובייקט auth המותאם אישית, מגדירים את השדה uid למזהה שבו השתמשתם כדי לייצג את השירות בכללי האבטחה.

Java
// Initialize the app with a custom auth variable, limiting the server's access
Map<String, Object> auth = new HashMap<String, Object>();
auth.put("uid", "my-service-worker");

FirebaseOptions options = FirebaseOptions.builder()
    .setCredentials(GoogleCredentials.getApplicationDefault())
    // The database URL depends on the location of the database
    .setDatabaseUrl("https://DATABASE_NAME.firebaseio.com")
    .setDatabaseAuthVariableOverride(auth)
    .build();
FirebaseApp.initializeApp(options);

// The app only has access as defined in the Security Rules
DatabaseReference ref = FirebaseDatabase
    .getInstance()
    .getReference("/some_resource");
ref.addListenerForSingleValueEvent(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        String res = dataSnapshot.getValue();
        System.out.println(res);
    }
});
Node.js
import { initializeApp } from 'firebase-admin/app';
import { getDatabase } from 'firebase-admin/database';

// Initialize the app with a custom auth variable, limiting the server's access
initializeApp({
  // The database URL depends on the location of the database
  databaseURL: "https://DATABASE_NAME.firebaseio.com",
  databaseAuthVariableOverride: {
    uid: "my-service-worker"
  }
});

// The app only has access as defined in the Security Rules
const db = getDatabase();
const ref = db.ref("/some_resource");
ref.once("value", (snapshot) => {
  console.log(snapshot.val());
});
Python
import firebase_admin
from firebase_admin import credentials
from firebase_admin import db

# Fetch the service account key JSON file contents
cred = credentials.Certificate('path/to/serviceAccountKey.json')

# Initialize the app with a custom auth variable, limiting the server's access
firebase_admin.initialize_app(cred, {
    'databaseURL': 'https://databaseName.firebaseio.com',
    'databaseAuthVariableOverride': {
        'uid': 'my-service-worker'
    }
})

# The app only has access as defined in the Security Rules
ref = db.reference('/some_resource')
print(ref.get())
המשך
ctx := context.Background()
// Initialize the app with a custom auth variable, limiting the server's access
ao := map[string]interface{}{"uid": "my-service-worker"}
conf := &firebase.Config{
	DatabaseURL:  "https://databaseName.firebaseio.com",
	AuthOverride: &ao,
}

// Fetch the service account key JSON file contents
opt := option.WithCredentialsFile("path/to/serviceAccountKey.json")

app, err := firebase.NewApp(ctx, conf, opt)
if err != nil {
	log.Fatalln("Error initializing app:", err)
}

client, err := app.Database(ctx)
if err != nil {
	log.Fatalln("Error initializing database client:", err)
}

// The app only has access as defined in the Security Rules
ref := client.NewRef("/some_resource")
var data map[string]interface{}
if err := ref.Get(ctx, &data); err != nil {
	log.Fatalln("Error reading from database:", err)
}
fmt.Println(data)

במקרים מסוימים, יכול להיות שתרצו לצמצם את ההיקף של ערכות ה-SDK לאדמינים כדי שהן יפעלו כלקוח לא מאומת. כדי לעשות זאת, צריך לספק ערך של null עבור שינוי משתנה האימות של מסד הנתונים.

Java
// Initialize the app with Application Default Credentials
FirebaseOptions options = FirebaseOptions.builder()
    .setCredentials(GoogleCredentials.getApplicationDefault())
    // The database URL depends on the location of the database
    .setDatabaseUrl("https://DATABASE_NAME.firebaseio.com")
    .setDatabaseAuthVariableOverride(null)
    .build();
FirebaseApp.initializeApp(options);

// The app only has access to public data as defined in the Security Rules
DatabaseReference ref = FirebaseDatabase
    .getInstance()
    .getReference("/public_resource");
ref.addListenerForSingleValueEvent(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        String res = dataSnapshot.getValue();
        System.out.println(res);
    }
});
Node.js
import { initializeApp } from 'firebase-admin/app';
import { getDatabase } from 'firebase-admin/database';

// Initialize the app with a null auth variable, limiting the server's access
initializeApp({
  // The database URL depends on the location of the database
  databaseURL: "https://DATABASE_NAME.firebaseio.com",
  databaseAuthVariableOverride: null
});

// The app only has access to public data as defined in the Security Rules
const db = getDatabase();
const ref = db.ref("/public_resource");
ref.once("value", (snapshot) => {
  console.log(snapshot.val());
});
Python
import firebase_admin
from firebase_admin import credentials
from firebase_admin import db

# Fetch the service account key JSON file contents
cred = credentials.Certificate('path/to/serviceAccountKey.json')

# Initialize the app with a None auth variable, limiting the server's access
firebase_admin.initialize_app(cred, {
    'databaseURL': 'https://databaseName.firebaseio.com',
    'databaseAuthVariableOverride': None
})

# The app only has access to public data as defined in the Security Rules
ref = db.reference('/public_resource')
print(ref.get())
המשך
ctx := context.Background()
// Initialize the app with a nil auth variable, limiting the server's access
var nilMap map[string]interface{}
conf := &firebase.Config{
	DatabaseURL:  "https://databaseName.firebaseio.com",
	AuthOverride: &nilMap,
}

// Fetch the service account key JSON file contents
opt := option.WithCredentialsFile("path/to/serviceAccountKey.json")

app, err := firebase.NewApp(ctx, conf, opt)
if err != nil {
	log.Fatalln("Error initializing app:", err)
}

client, err := app.Database(ctx)
if err != nil {
	log.Fatalln("Error initializing database client:", err)
}

// The app only has access to public data as defined in the Security Rules
ref := client.NewRef("/some_resource")
var data map[string]interface{}
if err := ref.Get(ctx, &data); err != nil {
	log.Fatalln("Error reading from database:", err)
}
fmt.Println(data)

השלבים הבאים