Admin SDK を使用すると、Realtime Database のデータの読み取りと書き込みを完全な管理者権限で実行することも、より細かく制限された権限で実行することもできます。このドキュメントでは、Firebase Realtime Database にアクセスできるように Firebase Admin SDK をプロジェクトに追加する方法について説明します。
Admin SDK の設定
Firebase Realtime Database をサーバー上で使い始めるには、まず、選択した言語で Firebase Admin SDK を設定する必要があります。
Admin SDK の認証
Firebase Admin SDK を使用してサーバーから Firebase Realtime Database にアクセスするには、あらかじめ Firebase でサーバーを認証しておく必要があります。サーバーを認証するときは、クライアント アプリで行うようにユーザー アカウントの認証情報を使用してログインするのではなく、Firebase に対してサーバーを識別するサービス アカウントで認証します。
Firebase Admin SDK を使用して認証すると、2 種類のアクセスレベルを取得できます。
Firebase Admin SDK の認証アクセスレベル | |
---|---|
管理者権限 | プロジェクトの Realtime Database に対する完全な読み取りおよび書き込みアクセス権。この権限は、プロジェクトのリソースへの無制限のアクセスが必要な管理者タスク(データの移行や再構築など)を実行する場合に注意して使用してください。 |
制限された権限 | プロジェクトの Realtime Database へのアクセス権。ただし、使用しているサーバーで必要とするリソースに限定されます。この権限は、アクセス要件が明確に定義されている管理者タスクを実行する場合に使用してください。たとえば、データベース全体でデータを読み取る要約ジョブを実行する場合、読み取り専用のセキュリティ ルールを設定し、そのルールで制限された権限で Admin SDK を初期化することによって、誤った書き込みを防止できます。 |
管理者権限による認証
Firebase プロジェクトに対する編集者のロールを持つサービス アカウントの認証情報を使用して Firebase Admin SDK を初期化すると、そのインスタンスはプロジェクトの Realtime Database への完全な読み取り / 書き込みアクセス権を持ちます。
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 = FirebaseOptions.builder() .setCredentials(GoogleCredentials.fromStream(serviceAccount)) // 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
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), // 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 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)) // 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
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), // 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 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)
Admin SDK を未認証クライアントとして機能させるのが適切な場合もあります。そのためには、データベースの auth 変数のオーバーライドに使用する値として null
を指定します。
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)) // 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
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), // 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 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)
次のステップ
- Realtime Database のデータを構造化する方法を学習する。
- 複数のデータベース インスタンスにデータをスケーリングする
- データを保存する
- データを取得する。
- Firebase コンソールでデータベースを表示する。