【Python】Firebaseでテナントごとにユーザー管理ができるよ

## Firebaseでユーザーをテナント(店舗)ごとに管理できるよ
テナント(店舗)単位でユーザーをユニークに管理する際にとっても便利
Firebase的にはマルチテナンシーって言うらしい
以下のイメージ
| 店舗名 | ユーザーID | なまえ             |
|:------|-----------:|:------------------|
| A店   | 1          | スーパーたろうさん |
| A店   | 2          | タコライス君       |
| B店   | 3          | スーパーたろうさん |

今回はフロント用のWeb SDKと管理用のAdmin SDKの使い方をまとめるよ
とりあえずGoogle Cloudでマルチテナンシーを有効にする必要があるよ
公式ドキュメントは↓
https://cloud.google.com/identity-platform/docs/multi-tenancy-quickstart?hl=ja
導入も簡単だから管理サイトのユーザー認証をFirebaseに丸投げできるね

## フロント側の実装(Web SDK バージョン9)
基本的にgetAuth後にtenantIdを指定するだけでマルチテナンシーを使わない場合とあまり変わらないよ
```javascript:javascript
import {
    initializeApp,
    getAuth
} from "firebase/app";

const firebaseConfig = {
    apiKey: "XXXXX",
    authDomain: "XXXXX.firebaseapp.com",
    projectId: "XXXXX",
    storageBucket: "XXXXX",
    messagingSenderId: "XXXXX",
    appId: "XXXXX"
};
const firebaseApp = initializeApp(firebaseConfig);
const auth = getAuth();
// テナント1を使用
auth.tenantId = "TENANT_ID1";
// テナント2へ切り替え
auth.tenantId = "TENANT_ID2";
```

### ログイン関係
既にauthにテナント情報が入っているのでテナントは意識しなくてOK
```javascript:javascript
import {
    initializeApp,
    getAuth,
    signInWithEmailAndPassword,
    GoogleAuthProvider,
    OAuthProvider,
    signInWithPopup
} from "firebase/app";

// メールパスワードログイン
signInWithEmailAndPassword(auth, email, password)
.then((result) => { const user = result.user; })
.catch((error) => { console.log("faild to login", error.code, error.message); });

// googleログイン
var provider_google = new GoogleAuthProvider();
signInWithPopup(auth, provider_google)
.then((result) => { const user = result.user; })
.catch((error) => { console.log("faild to login", error.code, error.message); });

// appleログイン
var provider_apple = new OAuthProvider("apple.com");
signInWithPopup(auth, provider_apple)
.then((result) => { const user = result.user; })
.catch((error) => { console.log("faild to login", error.code, error.message); });
```


## サーバーサイドの実装
今回はpythonでAdmin SDKを使っていくよ
テナントの作成からユーザーの操作ができるぜ

### テナント関係の操作
```python:python
import firebase_admin
from firebase_admin import credentials
from firebase_admin import tenant_mgt

# テナントの作成
tenant = tenant_mgt.create_tenant(
    display_name="てなんと１",
    allow_password_sign_up=True
)
print(f"Created tenant: {tenant.tenant_id}")

# テナントの更新
tenant = tenant_mgt.update_tenant(
    tenant_id,
    display_name="てなんと1・改",
    allow_password_sign_up=False
)
print(f"Updated tenant: {tenant.tenant_id}")
```

### ユーザー関係の操作
```python:python
cred = credentials.Certificate("./serviceAccountKey.json")
if not firebase_admin._apps:
    firebase_admin.initialize_app(cred)
tenant_client = tenant_mgt.auth_for_tenant('TestTenant1-4ygtb')

# ユーザー作成
user = tenant_client.create_user(
    email='user1@example.com',
    email_verified=False,
    phone_number='+819011111111',
    password='ぱすわーど',
    display_name='なまえ',
    photo_url='http://www.example.com/12345678/photo.png',
    disabled=False)

# トークン確認
decoded_firebase_token = tenant_client.verify_id_token(idToken)
uid = decoded_firebase_token["uid"]

# ユーザー情報更新
tenant_client.update_user(
    uid,
    email='user2@example.com',
    phone_number='+819011111111',
    email_verified=True,
    password='あたらしいぱすわーど',
    display_name='あたらしいなまえ',
    photo_url='http://www.example.com/12345678/photo.png',
    disabled=True
)

# ユーザー削除
auth.delete_user(uid)
```

## 最後に
Firebase全然知らんけどめっちゃ便利ね