実行環境
・Xcode Version 13.2.1
Firebase プロジェクト
開発環境と本番環境の分け方
Firebaseプロジェクトに設定するバンドルIDを本番用プロジェクトは本番のもの、開発用プロジェクトは後ろに-devなどを付けたものにし、Xcode側は開発中は以下のようにしておけば(良くないけど)ひとまず問題なさそう。(プロジェクト名は-prod/-devなど)
・バンドル ID:本番のもの+-devなどに変更する
・GoogleService-Info.plist:本番用のものをリネームしておき、開発用のをGoogleService-Info.plistとしておく
パッケージ
パッケージのインストール
Project > Package Dependenciesからインストール。
一部のライブラリをインストール後別のライブラリを追加する場合は、以下参照。
https://dev.classmethod.jp/articles/spm-add-new-package-product/
※サービスに対応するライブラリの一覧(公式):
https://firebase.google.com/docs/ios/setup?hl=ja
Remote Config
import FirebaseRemoteConfig
-----
@State var testFlagBool = false //@StateでもUserDefaultsでもなんでも用途に応じて
-----
let remoteConfig = RemoteConfig.remoteConfig()
let settings = RemoteConfigSettings()
settings.minimumFetchInterval = 0 //テストの場合
remoteConfig.configSettings = settings
remoteConfig.fetchAndActivate() { (status, error) -> Void in
if status == .successFetchedFromRemote || status == .successUsingPreFetchedData {
self.testFlagBool = remoteConfig.configValue(forKey: "testFlagBool").boolValue
} else {
print("Error: \(error?.localizedDescription ?? "No error available.")")
}
}
Authentication(匿名認証)
uid
iOSの場合、明示的に記述しない限り、端末に割り当てられるuidはアンインストールしてもずっと同じ。
Cloud FunctionsでのCustom Claim操作
const functions = require("firebase-functions");
const admin = require('firebase-admin');
admin.initializeApp();
//uidに対してカスタムクレームとしてroleとfamilyIdを付与する関数
exports.setCustomClaim = functions.https.onRequest((request, response) => {
functions.logger.info("setCustomClaim start uid: " + request.query.uid + ", role: " + request.query.role + ", familyId: " + request.query.familyId);
admin.auth().setCustomUserClaims(request.query.uid, {role: request.query.role, familyId: request.query.familyId}).then(() => {
response.send("OK");
functions.logger.info("setCustomClaim end uid: " + request.query.uid);
})
});
//uidに対してカスタムクレームを削除する関数
exports.deleteCustomClaim = functions.https.onRequest((request, response) => {
functions.logger.info("deleteCustomClaim start uid: " + request.query.uid);
admin.auth().setCustomUserClaims(request.query.uid, {role: null, familyId: null}).then(() => {
response.send("OK");
functions.logger.info("deleteCustomClaim end uid: " + request.query.uid);
})
});
Custom Claim操作後に情報を取得する際は、以下を使用し最新の情報を取得すること。
authResult?.user.getIDTokenResult(forcingRefresh: true)
Realtime Databaseのルール例
{
"rules": {
"test": {
"$uid": {
".read": "auth != null", //他のユーザーもreadする場合
// ".read": "auth != null && auth.uid == $uid", //自身のデータのみreadする場合
//".read": "auth.uid == 'hogehoge1234567890abcdefghijklmn'", //特定のuidのみreadする場合
".write": "$uid === auth.uid", //writeは自身のみの場合
//".write": false, //writeはしない場合
//".write": "auth.token.role == 'admin' && auth.token.familyId == $uid" //カスタムクレーム使用
}
}
}
}
Storageのルール例
service firebase.storage {
match /b/{bucket}/o {
match /{familyId}/{path=**} {
allow read: if request.auth.token.familyId == familyId;
allow write: if request.auth.token.familyId == familyId || request.auth.uid == familyId;
}
}
}