使用 Admin SDK,您能够以完整管理员权限或更细粒度的有限权限来读取和写入实时数据库数据。 在本文档中,我们会指导您将 Firebase Admin SDK 添加到项目中,以便能够访问 Firebase 实时数据库。
Admin SDK 设置
要在服务器上开始使用 Firebase 实时数据库,您需要先根据所选语言设置 Firebase Admin SDK。
Admin SDK 身份验证
使用 Firebase Admin SDK 从服务器访问 Firebase 实时数据库之前,您必须通过 Firebase 对服务器进行身份验证。当您对服务器进行身份验证时,无需像在客户端应用中那样通过用户帐号的凭据登录,而是通过服务帐号进行身份验证,服务帐号会向 Firebase 标识您的服务器身份。
使用 Firebase Admin SDK 进行身份验证时,您可以获得两种不同级别的访问权限:
Firebase Admin SDK 身份验证访问权限级别 | |
---|---|
管理员特权 | 拥有对项目实时数据库的完全读写权限。请将其谨慎地用于完成需要不受限地访问项目资源的管理任务(例如数据迁移或重组)。 |
有限特权 | 拥有对项目实时数据库的访问权限,但仅限于您的服务器需要的资源。使用此级别来完成已明确定义访问要求的管理任务。例如,当运行可读取整个数据库中的数据的摘要作业时,您可以设置一条只读安全规则,然后以该规则所规定的权限初始化 Admin SDK,从而防止意外写入。 |
以管理员特权进行身份验证
当您使用 Firebase 项目中具有编辑者角色的服务帐号凭据初始化 Firebase Admin SDK 时,该实例对项目实时数据库拥有完全的读写权限。
Java
// Fetch the service account key JSON file contents FileInputStream serviceAccount = new FileInputStream("path/to/serviceAccount.json"); // Initialize the app with a service account, granting admin privileges FirebaseOptions options = new FirebaseOptions.Builder() .setCredentials(GoogleCredentials.fromStream(serviceAccount)) .setDatabaseUrl("https://<databaseName>.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
var admin = require("firebase-admin"); // Fetch the service account key JSON file contents var serviceAccount = require("path/to/serviceAccountKey.json"); // Initialize the app with a service account, granting admin privileges admin.initializeApp({ credential: admin.credential.cert(serviceAccount), databaseURL: "https://databaseName.firebaseio.com" }); // As an admin, the app has access to read and write all data, regardless of Security Rules var db = admin.database(); var ref = db.ref("restricted_access/secret_document"); ref.once("value", function(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())
Go
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
// Fetch the service account key JSON file contents FileInputStream serviceAccount = new FileInputStream("path/to/serviceAccountCredentials.json"); // 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 = new FirebaseOptions.Builder() .setCredential(FirebaseCredentials.fromCertificate(serviceAccount)) .setDatabaseUrl("https://databaseName.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
var admin = require("firebase-admin"); // Fetch the service account key JSON file contents var serviceAccount = require("path/to/serviceAccountKey.json"); // Initialize the app with a custom auth variable, limiting the server's access admin.initializeApp({ credential: admin.credential.cert(serviceAccount), databaseURL: "https://databaseName.firebaseio.com", databaseAuthVariableOverride: { uid: "my-service-worker" } }); // The app only has access as defined in the Security Rules var db = admin.database(); var ref = db.ref("/some_resource"); ref.once("value", function(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())
Go
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)
null
值以用于覆盖数据库 auth 变量。
Java
// Fetch the service account key JSON file contents FileInputStream serviceAccount = new FileInputStream("path/to/serviceAccountCredentials.json"); FirebaseOptions options = new FirebaseOptions.Builder() .setCredential(FirebaseCredentials.fromCertificate(serviceAccount)) .setDatabaseUrl("https://databaseName.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
var admin = require("firebase-admin"); // Fetch the service account key JSON file contents var serviceAccount = require("path/to/serviceAccountKey.json"); // Initialize the app with a null auth variable, limiting the server's access admin.initializeApp({ credential: admin.credential.cert(serviceAccount), databaseURL: "https://databaseName.firebaseio.com", databaseAuthVariableOverride: null }); // The app only has access to public data as defined in the Security Rules var db = admin.database(); var ref = db.ref("/public_resource"); ref.once("value", function(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())
Go
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)
后续步骤
- 了解如何为实时数据库设计数据结构。
- 将数据扩展到多个数据库实例。
- 保存数据。
- 检索数据。
- 在 Firebase 控制台中查看您的数据库。