Firebase 安裝服務 (FIS) 會為每個已安裝的 Firebase 應用程式執行個體提供 Firebase 安裝 ID (FID)。下列 Firebase 服務會在內部使用 Firebase 安裝 ID:
| Firebase 服務 | Firebase 安裝功能 |
|---|---|
| Firebase Cloud Messaging |
Firebase Cloud Messaging 會使用 Firebase 安裝 ID 指定要傳送訊息的裝置。 |
| Firebase Crashlytics |
Firebase Crashlytics 會根據應用程式執行個體的 Firebase 安裝 ID 變更,輪替 Crashlytics 安裝 UUID。日後,安裝 ID 可能會用於啟用功能,強化當機回報和當機管理服務。 |
| Firebase In-App Messaging |
Firebase In-App Messaging 會使用 Firebase 安裝 ID 指定要傳送訊息的目標裝置。 |
| Firebase Performance Monitoring |
Performance Monitoring 會使用 Firebase 安裝 ID 計算存取網路資源的不重複 Firebase 安裝次數,確保存取模式充分匿名。此外,SDK 也會使用 Firebase 安裝 ID 和 Firebase Remote Config,管理成效事件回報頻率。 |
| Firebase Remote Config |
Remote Config 會使用 Firebase 安裝 ID 選取要傳回使用者裝置的設定值。Remote Config 個人化功能會使用 Firebase 安裝 ID,將應用程式事件資料與 Firebase 安裝建立關聯,以便預測並將最佳設定值傳回使用者裝置。 |
| Firebase ML |
Firebase ML 會使用名為 安裝驗證權杖的憑證,在與應用程式執行個體互動時驗證裝置,例如將開發人員模型發布至應用程式執行個體。 |
| Firebase 使用者區隔儲存空間 |
Firebase 使用者區隔儲存空間會儲存 Firebase 安裝 ID 和相關屬性與區隔,為其他使用這些資訊的 Firebase 服務提供指定目標資訊。 |
一般來說,Firebase 服務會使用 Firebase 安裝服務,開發人員不需要直接與 FIS API 互動。不過,在某些情況下,應用程式開發人員可能需要直接呼叫 FIS API,例如:
- 刪除 Firebase 安裝項目和相關資料。
- 擷取 ID (Firebase 安裝 ID),指定特定應用程式安裝。
- 擷取安裝驗證權杖,驗證 Firebase 安裝。
如要開始直接呼叫 FIS API,請將 SDK 新增至應用程式。
在應用程式中加入 Firebase 安裝 SDK
iOS+
- 在 Podfile 中新增 Firebase 安裝作業的依附元件:
pod 'FirebaseInstallations'
- 執行
pod install並開啟建立的.xcworkspace檔案。 - 在
UIApplicationDelegate中匯入FirebaseCore模組,以及應用程式委派使用的任何其他 Firebase 模組。舉例來說,如要使用 Cloud Firestore 和 Authentication,請按照下列步驟操作:SwiftUI
import SwiftUI import FirebaseCore import FirebaseFirestore import FirebaseAuth // ...
Swift
import FirebaseCore import FirebaseFirestore import FirebaseAuth // ...
Objective-C
@import FirebaseCore; @import FirebaseFirestore; @import FirebaseAuth; // ...
- 在應用程式委派的
application(_:didFinishLaunchingWithOptions:)方法中,設定FirebaseApp共用例項:SwiftUI
// Use Firebase library to configure APIs FirebaseApp.configure()
Swift
// Use Firebase library to configure APIs FirebaseApp.configure()
Objective-C
// Use Firebase library to configure APIs [FIRApp configure];
- 如果您使用 SwiftUI,則必須建立應用程式委派,並透過
UIApplicationDelegateAdaptor或NSApplicationDelegateAdaptor將其附加至App結構。您也必須停用應用程式委派物件重組。詳情請參閱 SwiftUI 操作說明。SwiftUI
@main struct YourApp: App { // register app delegate for Firebase setup @UIApplicationDelegateAdaptor(AppDelegate.self) var delegate var body: some Scene { WindowGroup { NavigationView { ContentView() } } } }
Android
將 Firebase 安裝 Android SDK 的依附元件加進模組的 (應用程式層級) Gradle 檔案 (通常位於 app/build.gradle):
implementation 'com.google.firebase:firebase-installations:20.0.0'
JavaScript
視網頁應用程式的託管方式而定,系統可能會自動處理設定,也可能需要您更新 Firebase 設定物件。
舉例來說,如果依附元件是加在 index.html 中,請在 <head> 元素中加入依附元件:
<script src="/__/firebase/13.0.0/firebase-installations.js"></script>
Flutter
在 Flutter 專案的根目錄中,執行下列指令來安裝 Firebase 安裝外掛程式:
flutter pub add firebase_app_installations重建專案:
flutter run匯入 Firebase 安裝外掛程式:
import 'package:firebase_app_installations/firebase_app_installations.dart';
刪除 Firebase 安裝
與 Firebase 安裝相關聯的資料通常「不」屬於個人識別資訊。不過,建議您提供選項,讓使用者管理及刪除這類資料。
每個應用程式的每次安裝都有不同的 Firebase 安裝 ID;同一部裝置上的不同應用程式也有不同的 Firebase 安裝 ID。Firebase 安裝 ID 可識別應用程式安裝,以及與這些安裝相關聯的資料。
刪除安裝 ID 時,與該安裝 ID 相關聯的資料會從所有使用 Firebase 安裝 ID 識別安裝的 Firebase 服務的即時和備份系統中移除,時間為 180 天內。Google 的刪除和保留聲明概略說明瞭這項程序。
除非您在應用程式中停用所有會產生 FID 的服務,否則 FIS 會在幾天內建立新的 ID。Firebase 會將新建立的 ID 視為新的 Firebase 安裝,且不會以任何方式將其與先前的 ID 或資料建立關聯。
使用用戶端 API 呼叫刪除 FID
如要刪除 Firebase 服務產生的 FID,請從 Firebase 安裝 SDK 呼叫適當的方法:
Swift
do { try await Installations.installations().delete() print("Installation deleted"); } catch { print("Error deleting installation: \(error)") }
Objective-C
[[FIRInstallations installations] deleteWithCompletion:^(NSError *error) { if (error != nil) { NSLog(@"Error deleting Installation %@", error); return; } NSLog(@"Installation deleted"); }];
Java
FirebaseInstallations.getInstance().delete() .addOnCompleteListener(new OnCompleteListener<Void>() { @Override public void onComplete(@NonNull Task<Void> task) { if (task.isSuccessful()) { Log.d("Installations", "Installation deleted"); } else { Log.e("Installations", "Unable to delete Installation"); } } });
Kotlin
FirebaseInstallations.getInstance().delete().addOnCompleteListener { task -> if (task.isComplete) { Log.d("Installations", "Installation deleted") } else { Log.e("Installations", "Unable to delete Installation") } }
JavaScript
await firebase.installations().delete();
Dart
await FirebaseInstallations.instance.delete();
透過伺服器 API 呼叫刪除 FID
如要透過伺服器 API 呼叫刪除 FID,請將 Firebase Admin SDK 新增至伺服器 (如果尚未新增)。
新增 SDK 後,請呼叫所選語言的刪除函式來刪除 FID (注意:除了 Node.js 以外,這些方法會反映執行個體 ID 命名。不過,使用任何目前的 Firebase SDK 呼叫時,這些方法實際上都會刪除 FID。
Node.js
// An FIDsent from a client service SDK
const idToDelete = 'eyJhbGciOiJFUzI1N_iIs5';
admin.installations().deleteInstallation(idToDelete);
Java
// An FID sent from a client service SDK
String idToDelete = "eyJhbGciOiJFUzI1N_iIs5";
FirebaseInstanceId.getInstance().deleteInstanceIdAsync(idToDelete).get();
Python
from firebase_admin import instance_id
# An FID sent from a client service SDK
id_to_delete = 'eyJhbGciOiJFUzI1N_iIs5'
instance_id.delete_instance_id(id_to_delete)
Go
client, err := app.InstanceId(ctx)
if err != nil {
log.Fatalln("error initializing client", err)
}
iidToDelete := "eyJhbGciOiJFUzI1N_iIs5"
if err := client.DeleteInstanceId(ctx, iidToDelete); err != nil {
log.Fatalln("error deleting FID", err)
}
使用伺服器 API 呼叫刪除 Firebase 安裝 ID 後,Firebase 服務會開始刪除與該安裝 ID 相關聯的資料,並在 1 到 2 天內停止接受該 ID 的新資料,然後通知用戶端應用程式該 ID 已刪除。在 Firebase 通知用戶端應用程式之前,部分應用程式服務可能仍會指定該 ID,例如 Firebase 安裝作業可能會在幾小時內繼續收到 FCM 通知。
如要刪除目前的 Firebase 安裝 ID,並立即使用新的不相關 ID 存取 Firebase 服務,請使用用戶端 API 處理刪除作業。
擷取用戶端 ID
如需識別應用程式的特定安裝,可以擷取 Firebase 安裝 ID。舉例來說,如要建立應用程式安裝區隔以匯入 BigQuery,或在 Firebase In-App Messaging 開發期間進行測試,您可以使用對應的 Firebase 安裝 ID 識別及指定正確的裝置。
如要擷取 Firebase 安裝 ID,請按照下列步驟操作:
Swift
do { let id = try await Installations.installations().installationID() print("Installation ID: \(id)") } catch { print("Error fetching id: \(error)") }
Objective-C
[[FIRInstallations installations] installationIDWithCompletion:^(NSString *identifier, NSError *error) { if (error != nil) { NSLog(@"Error fetching Installation ID %@", error); return; } NSLog(@"Installation ID: %@", identifier); }];
Java
FirebaseInstallations.getInstance().getId() .addOnCompleteListener(new OnCompleteListener<String>() { @Override public void onComplete(@NonNull Task<String> task) { if (task.isSuccessful()) { Log.d("Installations", "Installation ID: " + task.getResult()); } else { Log.e("Installations", "Unable to get Installation ID"); } } });
Kotlin
FirebaseInstallations.getInstance().id.addOnCompleteListener { task -> if (task.isSuccessful) { Log.d("Installations", "Installation ID: " + task.result) } else { Log.e("Installations", "Unable to get Installation ID") } }
JavaScript
const installationId = await firebase.installations().getId(); console.log(installationId);
Dart
String id = await FirebaseInstallations.instance.getId();
擷取安裝驗證權杖
Firebase 服務可以使用從 FIS 擷取的驗證權杖,驗證 Firebase 安裝。舉例來說,為 Remote Config 設計 A/B 測試時,您可以使用安裝授權權杖驗證指定的測試裝置。
安裝驗證權杖是 JSON Web Token (JWT) 格式的短期不記名權杖,包含下列安裝資訊:
- Firebase 安裝 ID
- 相關聯的專案 (
projectNumber) - 相關聯的 Firebase 應用程式 ID (
appId) - 權杖到期日
安裝授權權杖無法撤銷,在到期日前都有效。預設權杖生命週期為一週。
如要擷取安裝授權權杖,請按照下列步驟操作:
Swift
do { let result = try await Installations.installations() .authTokenForcingRefresh(true) print("Installation auth token: \(result.authToken)") } catch { print("Error fetching token: \(error)") }
Objective-C
[[FIRInstallations installations] authTokenForcingRefresh:true completion:^(FIRInstallationsAuthTokenResult *result, NSError *error) { if (error != nil) { NSLog(@"Error fetching Installation token %@", error); return; } NSLog(@"Installation auth token: %@", [result authToken]); }];
Java
FirebaseInstallations.getInstance().getToken(/* forceRefresh */true) .addOnCompleteListener(new OnCompleteListener<InstallationTokenResult>() { @Override public void onComplete(@NonNull Task<InstallationTokenResult> task) { if (task.isSuccessful() && task.getResult() != null) { Log.d("Installations", "Installation auth token: " + task.getResult().getToken()); } else { Log.e("Installations", "Unable to get Installation auth token"); } } });
Kotlin
val forceRefresh = true FirebaseInstallations.getInstance().getToken(forceRefresh) .addOnCompleteListener { task -> if (task.isSuccessful) { Log.d("Installations", "Installation auth token: " + task.result?.token) } else { Log.e("Installations", "Unable to get Installation auth token") } }
JavaScript
const installationToken = await firebase.installations() .getToken(/* forceRefresh */ true); console.log(installationToken);
Dart
String token = await FirebaseInstallations.instance.getToken();
監控 Firebase 安裝 ID 生命週期
在應用程式正常運作期間,Firebase 安裝 ID (FID) 不需要特別監控。不過,如果應用程式會明確擷取及使用 FID,則應新增邏輯,監控 FID 是否可能遭到刪除或輪替。以下是 FID 可能遭到刪除或輪替的情況:
- 解除安裝或重新安裝應用程式,例如使用者在新裝置上安裝。
- 使用者清除應用程式或裝置的快取。
- 由於應用程式閒置 (目前門檻為閒置 270 天),後端會觸發 FID 刪除作業。
在這種情況下,如果應用程式的 FID 遭到輪替或刪除,系統會指派新的 FID。此外,與已刪除 FID 相關聯的安裝驗證權杖也會刪除 (無論其本身是否已過期),並替換為新的安裝驗證權杖。
應用程式可以監控這些變更,並做出相應回應。
如要監控 FID 輪替,請按照下列步驟操作:
Swift
installationIDObserver = NotificationCenter.default.addObserver( forName: .InstallationIDDidChange, object: nil, queue: nil ) { (notification) in // Fetch new Installation ID Task { await self.fetchInstallationToken() } }
Objective-C
__weak __auto_type weakSelf = self; self.installationIDObserver = [[NSNotificationCenter defaultCenter] addObserverForName: FIRInstallationIDDidChangeNotification object:nil queue:nil usingBlock:^(NSNotification * _Nonnull notification) { // Fetch new Installation ID [weakSelf fetchInstallationsID]; }];
每當系統指派新的 FID 時,名為 NSNotificationName.InstallationIDDidChange 的 NSNotification 就會發布至預設的 NSNotificationCenter。
Android
Kotlin 和 Java 用戶端應加入重試邏輯,在擷取新 FID 的呼叫失敗時做出回應。
JavaScript
網頁應用程式可以訂閱 onIdChange 鉤。
每當建立新的 FID 時,系統就會觸發訂閱的回呼:
await firebase.installations().onIdChange((newId) => { console.log(newId); // TODO: Handle new installation ID. });
Dart
FirebaseInstallations.instance.onIdChange.listen((token) {
print('FID token: $token');
});
從執行個體 ID 遷移至 Firebase 安裝
在推出 Firebase 安裝之前,Firebase 仰賴 Instance ID SDK 取得應用程式安裝 ID。相較於執行個體 ID,Firebase 安裝在可靠性、效能和安全性方面具有顯著優勢。如果 Firebase 應用程式依賴 Instance ID SDK,請遷移至 Firebase 安裝。
遷移程序會因應用程式而異:
如果應用程式未直接呼叫 Instance ID API,可以更新 SDK 版本來遷移。大多數 Firebase 應用程式都屬於這個類別。
如果應用程式明確對 Instance ID 發出 API 呼叫,則必須更新 SDK 版本和 變更程式碼,將 Instance ID 方法替換為 Firebase 安裝或 FCM 對等方法。如果應用程式使用執行個體 ID 擷取 FCM 註冊權杖,或明確使用執行個體 ID 指定應用程式執行個體或用於其他用途,則必須更新應用程式程式碼。
目前,FIS 與舊版 ID Firebase 執行個體 ID 回溯相容。刪除 IID 是使用下列 Firebase SDK 要求刪除資料的替代方法:
- iOS 6.14.0 以下版本
- 2020 年 2 月 27 日前推出的 Android SDK
也就是說,應用程式「不一定要」遷移至 Firebase 安裝,但強烈建議這麼做。
升級至 Firebase 安裝項目的最低 SDK 版本
如要從執行個體 ID 遷移至 Firebase 安裝,請確認應用程式至少使用下列 Firebase SDK 的最低版本號碼:
| Firebase SDK | Android 最低版本 | 最低 iOS 版本 |
| Firebase 雲端通訊 | v20.3.0 | v6.34.0 |
| 遠端設定 | v19.2.0 | v6.24.0 |
| Google Analytics for Firebase \ (評估 SDK) | v17.4.4 | v6.18.0 |
| 應用程式內訊息 | v19.0.7 | v6.24.0 |
| Performance Monitoring | v19.0.8 | v6.21.0 |
| Crashlytics | v17.2.1 | v6.23.0 |
| ML Kit | v22.1.2 | v6.28.0 |
更新明確呼叫 Instance ID API 的程式碼
如果 Android 或 Apple 應用程式直接使用 Instance ID SDK 方法,您可以使用 Firebase 安裝 SDK 或 FCM SDK 中的相同替代方法。
擷取 ID
取得執行個體 ID 的方法已替換為取得安裝 ID 的方法。例如:
之前
Swift
Messaging.messaging().token { token, error in if let error = error { print("Error fetching remote FCM registration token: \(error)") } else if let token = token { print("Remote instance ID token: \(token)") } }
Objective-C
[[FIRMessaging messaging] tokenWithCompletion:^(NSString * _Nullable token, NSError * _Nullable error) { if (error != nil) { NSLog(@"Error fetching the remote FCM registration token: %@", error); } else { NSLog(@"Remote FCM registration token: %@", token); NSString* message = [NSString stringWithFormat:@"FCM registration token: %@", token]; // display message NSLog(@"%@", message); } }];
Java
FirebaseInstanceId.getInstance().getInstanceId() .addOnCompleteListener(new OnCompleteListener<InstanceIdResult>() { @Override public void onComplete(@NonNull Task<InstanceIdResult> task) { Log.d("IID_TOKEN", task.getResult().getToken()); } });
Kotlin
FirebaseInstanceId.getInstance().instanceId .addOnSuccessListener { result -> Log.d("IID_TOKEN", result.token) }
之後
Swift
do { let id = try await Installations.installations().installationID() print("Installation ID: \(id)") } catch { print("Error fetching id: \(error)") }
Objective-C
[[FIRInstallations installations] installationIDWithCompletion:^(NSString *identifier, NSError *error) { if (error != nil) { NSLog(@"Error fetching Installation ID %@", error); return; } NSLog(@"Installation ID: %@", identifier); }];
Java
FirebaseInstallations.getInstance().getId() .addOnCompleteListener(new OnCompleteListener<String>() { @Override public void onComplete(@NonNull Task<String> task) { if (task.isSuccessful()) { Log.d("Installations", "Installation ID: " + task.getResult()); } else { Log.e("Installations", "Unable to get Installation ID"); } } });
Kotlin
FirebaseInstallations.getInstance().id.addOnCompleteListener { task -> if (task.isSuccessful) { Log.d("Installations", "Installation ID: " + task.result) } else { Log.e("Installations", "Unable to get Installation ID") } }
刪除 ID
刪除執行個體 ID 的方法會由刪除 Firebase 安裝 ID 的方法取代。例如:
之前
Swift
InstanceID.instanceID().deleteID { error in
if let error = error {
print("Error deleting instance ID: \(error)")
}
}
Objective-C
[FIRInstanceID instanceID] deleteIDWithHandler:^(NSError *error) {
if error != nil {
NSLog(@"Error deleting instance ID: %@", error);
}
}];
Android
FirebaseInstanceId.deleteInstanceId();
之後
Swift
func delete(completion: @escaping (Error?) -> Void)
Objective-C
- (void)deleteWithCompletion:(nonnull void (^)(NSError *_Nullable))completion;
Java
FirebaseInstallations.getInstance().delete() .addOnCompleteListener(new OnCompleteListener<Void>() { @Override public void onComplete(@NonNull Task<Void> task) { if (task.isSuccessful()) { Log.d("Installations", "Installation deleted"); } else { Log.e("Installations", "Unable to delete Installation"); } } });
Kotlin
FirebaseInstallations.getInstance().delete().addOnCompleteListener { task -> if (task.isComplete) { Log.d("Installations", "Installation deleted") } else { Log.e("Installations", "Unable to delete Installation") } }
正在擷取 FCM 註冊權杖
在 Firebase 安裝服務推出前,FCM 用戶端會從執行個體 ID 擷取註冊權杖。現在,FCM SDK 提供擷取註冊權杖的方法。
之前
Java
FirebaseInstanceId.getInstance().getInstanceId() .addOnCompleteListener(new OnCompleteListener<InstanceIdResult>() { @Override public void onComplete(@NonNull Task<InstanceIdResult> task) { if (!task.isSuccessful()) { Log.w(TAG, "getInstanceId failed", task.getException()); return; } // Get new Instance ID token String token = task.getResult().getToken(); // Log and toast String msg = getString(R.string.msg_token_fmt, token); Log.d(TAG, msg); Toast.makeText(MainActivity.this, msg, Toast.LENGTH_SHORT).show(); } });
Kotlin
FirebaseInstanceId.getInstance().instanceId .addOnCompleteListener(OnCompleteListener { task -> if (!task.isSuccessful) { Log.w(TAG, "getInstanceId failed", task.exception) return@OnCompleteListener } // Get new Instance ID token val token = task.result?.token // Log and toast val msg = getString(R.string.msg_token_fmt, token) Log.d(TAG, msg) Toast.makeText(baseContext, msg, Toast.LENGTH_SHORT).show() })
Swift
InstanceID.instanceID().instanceID { result, error in if let error = error { print("Error fetching instance ID: \(error)") } else if let result = result { print("Instance ID token: \(result.token)") } }
Objective-C
[[FIRInstanceID instanceID] instanceIDWithHandler:^(FIRInstanceIDResult * _Nullable result, NSError * _Nullable error) { if (error != nil) { NSLog(@"Error fetching instance ID: %@", error); } else { NSLog(@"Instance ID token: %@", result.token); } }];
之後
Java
FirebaseMessaging.getInstance().getToken() .addOnCompleteListener(new OnCompleteListener<String>() { @Override public void onComplete(@NonNull Task<String> task) { if (!task.isSuccessful()) { Log.w(TAG, "Fetching FCM registration token failed", task.getException()); return; } // Get new FCM registration token String token = task.getResult(); // Log and toast String msg = getString(R.string.msg_token_fmt, token); Log.d(TAG, msg); Toast.makeText(MainActivity.this, msg, Toast.LENGTH_SHORT).show(); } });
Kotlin
FirebaseMessaging.getInstance().token.addOnCompleteListener(OnCompleteListener { task -> if (!task.isSuccessful) { Log.w(TAG, "Fetching FCM registration token failed", task.exception) return@OnCompleteListener } // Get new FCM registration token val token = task.result // Log and toast val msg = getString(R.string.msg_token_fmt, token) Log.d(TAG, msg) Toast.makeText(baseContext, msg, Toast.LENGTH_SHORT).show() })
Swift
Messaging.messaging().token { token, error in if let error = error { print("Error fetching remote FCM registration token: \(error)") } else if let token = token { print("Remote instance ID token: \(token)") } }
Objective-C
[[FIRMessaging messaging] tokenWithCompletion:^(NSString * _Nullable token, NSError * _Nullable error) { if (error != nil) { NSLog(@"Error fetching the remote FCM registration token: %@", error); } else { NSLog(@"Remote FCM registration token: %@", token); NSString* message = [NSString stringWithFormat:@"FCM registration token: %@", token]; // display message NSLog(@"%@", message); } }];