Google 致力于为黑人社区推动种族平等。查看具体举措

管理 Firebase 安装

使用集合让一切井井有条 根据您的偏好保存内容并对其进行分类。

Firebase 安装服务 (FIS) 为每个已安装的 Firebase 应用实例提供一个 Firebase 安装 ID (FID)。 Firebase 安装 ID 由以下 Firebase 服务在内部使用:

火力地堡服务Firebase 安装功能
Firebase 云消息传递

Firebase 云消息传递使用 Firebase 安装 ID 来定位设备以进行消息传递。

Firebase 应用内消息

Firebase 应用内消息使用 Firebase 安装 ID 来定位设备以进行消息传递。

Firebase 性能监控

性能监控使用 Firebase 安装 ID 来计算访问网络资源的唯一 Firebase 安装数量,以确保访问模式充分匿名。它还使用 Firebase 安装 ID 和 Firebase Remote Config 来管理性能事件报告的速率。

Firebase 远程配置

Remote Config 使用 Firebase 安装 ID 来选择配置值以返回给最终用户设备。

火力地堡机器学习

在与应用程序实例交互时,Firebase ML 使用称为安装身份验证令牌的凭证进行设备身份验证,例如,将开发人员模型分发到应用程序实例。

Firebase 用户细分存储

Firebase User Segmentation Storage 存储 Firebase 安装 ID 和相关属性和细分,以便为使用它们的其他 Firebase 服务提供定位信息。

通常,Firebase 服务使用 Firebase 安装服务,无需开发人员直接与 FIS API 交互。但是,在某些情况下,应用程序开发人员可能希望直接调用 FIS API,例如:

  • 删除 Firebase 安装和与安装相关的数据。
  • 检索标识符(Firebase 安装 ID)以定位特定的应用程序安装。
  • 检索安装身份验证令牌以验证 Firebase 安装。

要开始直接调用 FIS API,请将 SDK 添加到您的应用程序。

将 Firebase 安装 SDK 添加到您的应用

iOS+

  1. 将 Firebase 安装的依赖项添加到 Podfile:
    pod 'FirebaseInstallations'
  2. 运行pod install并打开创建的.xcworkspace文件。
  3. 在您的UIApplicationDelegate中导入FirebaseCore模块,以及您的应用委托使用的任何其他Firebase 模块。例如,要使用 Cloud Firestore 和身份验证:

    斯威夫特用户界面

    import SwiftUI
    import FirebaseCore
    import FirebaseFirestore
    import FirebaseAuth
    // ...
          

    迅速

    import FirebaseCore
    import FirebaseFirestore
    import FirebaseAuth
    // ...
          

    目标-C

    @import FirebaseCore;
    @import FirebaseFirestore;
    @import FirebaseAuth;
    // ...
          
  4. 在您的应用委托的application(_:didFinishLaunchingWithOptions:)方法中配置一个FirebaseApp共享实例:

    斯威夫特用户界面

    // Use Firebase library to configure APIs
    FirebaseApp.configure()

    迅速

    // Use Firebase library to configure APIs
    FirebaseApp.configure()

    目标-C

    // Use Firebase library to configure APIs
    [FIRApp configure];
  5. 如果您使用的是 SwiftUI,则必须创建一个应用程序委托并通过UIApplicationDelegateAdaptorNSApplicationDelegateAdaptor将其附加到您的App结构。您还必须禁用应用委托调配。有关详细信息,请参阅SwiftUI 说明

    斯威夫特用户界面

    @main
    struct YourApp: App {
      // register app delegate for Firebase setup
      @UIApplicationDelegateAdaptor(AppDelegate.self) var delegate
    
      var body: some Scene {
        WindowGroup {
          NavigationView {
            ContentView()
          }
        }
      }
    }
          

安卓

将 Firebase 安装 Android SDK 的依赖项添加到您的模块(应用程序级)Gradle 文件(通常是app/build.gradle ):

implementation 'com.google.firebase:firebase-installations:17.1.0'

JavaScript

根据您的 Web 应用程序的托管方式,您的配置可能会自动处理,或者您可能需要更新您的Firebase 配置对象

例如,如果您的依赖项添加在 index.html 中,请在 <head> 元素中添加依赖项:

<script src="/__/firebase/9.16.0/firebase-installations.js"></script>

  1. 在 Flutter 项目的根目录中,运行以下命令来安装 Firebase 安装插件:

    flutter pub add firebase_app_installations
    
  2. 重建你的项目:

    flutter run
    
  3. 导入 Firebase 安装插件:

    import 'package:firebase_app_installations/firebase_app_installations.dart';
    

删除 Firebase 安装

与 Firebase 安装相关的数据通常无法识别个人身份。尽管如此,为用户提供管理和删除这些数据的选项还是很有帮助的。

每个应用程序的每次安装的 Firebase 安装 ID 都是不同的;同一设备上的不同应用程序具有不同的 Firebase 安装 ID。 Firebase 安装 ID 标识应用程序安装以及与这些应用程序安装相关的数据。

当您删除安装 ID 时,与该安装 ID 关联的数据会在 180 天内从使用 Firebase 安装 ID 识别安装的所有 Firebase 服务的实时和备份系统中删除。 Google关于删除和保留的声明在较高层次上描述了此过程。

除非您在应用程序中禁用所有生成 FID 的服务,否则 FIS 会在几天内创建一个新 ID。 Firebase 将新创建的 ID 视为新的 Firebase 安装,并且不会以任何方式将其与以前的 ID 或数据相关联。

使用客户端 API 调用删除 FID

要删除 Firebase 服务生成的 FID,请从 Firebase 安装 SDK 调用适当的方法:

迅速

Installations.installations().delete { error in
  if let error = error {
    print("Error deleting installation: \(error)")
    return
  }
  print("Installation deleted");
}

目标-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+KTX

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 调用时,它们实际上都删除了 FID开发工具包)。

节点.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)

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 来处理删除操作。

检索客户端标识符

如果您需要识别应用的特定安装,您可以通过检索 Firebase 安装 ID 来实现。例如,要在 Firebase 应用内消息开发期间执行测试,您可以使用其 Firebase 安装 ID 识别和定位正确的测试设备。

要检索 Firebase 安装 ID:

迅速

Installations.installations().installationID { (id, error) in
  if let error = error {
    print("Error fetching id: \(error)")
    return
  }
  guard let id = id else { return }
  print("Installation ID: \(id)")
}

目标-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+KTX

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 令牌 (JWT) 格式的短期不记名令牌,包含以下安装信息:

  • Firebase 安装 ID
  • 关联项目 ( projectNumber )
  • 关联的 Firebase 应用程序 ID ( appId )
  • 令牌的到期日期

安装授权令牌无法撤销,并且在其到期日期之前一直有效。默认令牌生命周期为一周。

要检索安装授权令牌:

迅速

Installations.installations().authTokenForcingRefresh(true, completion: { (result, error) in
  if let error = error {
    print("Error fetching token: \(error)")
    return
  }
  guard let result = result else { return }
  print("Installation auth token: \(result.authToken)")
})

目标-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+KTX

FirebaseInstallations.getInstance().getToken(/* forceRefresh */ true)
    .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 旋转:

迅速

installationIDObserver = NotificationCenter.default.addObserver(
        forName: .InstallationIDDidChange,
        object: nil,
        queue: nil
) { (notification) in
  // Fetch new Installation ID
  self.fetchInstallationToken()
}

目标-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。

安卓

Kotlin 和 Java 客户端应添加重试逻辑以响应失败的调用以检索新的 FID。

JavaScript

Web 应用程序可以订阅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 作为应用安装的标识符。与 Instance ID 相比,Firebase 安装在可靠性、性能和安全性方面具有显着优势。依赖于 Instance ID SDK 的 Firebase 应用程序应该迁移到 Firebase 安装。

迁移过程因您的应用而异:

  • 不直接调用 Instance ID API 的应用程序可以通过更新其 SDK 版本进行迁移。大多数 Firebase 应用都属于这一类。

  • 明确对实例 ID 进行 API 调用的应用程序必须更新 SDK 版本进行代码更改,以将实例 ID 方法替换为其 Firebase 安装或 FCM 等效方法。如果您的应用程序使用实例 ID 来检索 FCM 注册令牌或明确使用实例 ID 来定位应用程序实例或用于任何其他目的,您将需要更新您的应用程序代码。

目前,FIS 向后兼容旧标识符 Firebase 实例 ID。删除 IID是使用这些 Firebase SDK 请求删除数据的替代方法:

  • iOS 6.14.0 及更低版本
  • 2020 年 2 月 27 日之前的 Android SDK

这意味着应用程序不需要迁移到 Firebase 安装;但是,强烈建议这样做。

升级到 Firebase 安装的最低 SDK 版本

要从实例 ID 迁移到 Firebase 安装,请确保您的应用程序至少使用以下 Firebase SDK 列出的最低版本号:

火力地堡SDK最低安卓版本最低 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
性能监控v19.0.8 v6.21.0
崩溃分析v17.2.1 v6.23.0
机器学习套件v22.1.2 v6.28.0

更新显式调用实例 ID API 的代码

如果您的 Android 或 Apple 应用程序直接使用 Instance ID SDK 方法,您可以在 Firebase 安装 SDK 或 FCM SDK 中用相同的替代方法替换该用法。

检索标识符

获取实例 ID 的方法被替换为获取安装 ID 的方法。例如:

迅速

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)")
    self.remoteFCMTokenMessage.text = "Remote FCM registration token: \(token)"
  }
}

目标-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];
     self.remoteFCMTokenMessage.text = 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+KTX

FirebaseInstanceId.getInstance().instanceId
        .addOnSuccessListener { result ->
            Log.d("IID_TOKEN", result.token)
        }

迅速

Installations.installations().installationID { (id, error) in
  if let error = error {
    print("Error fetching id: \(error)")
    return
  }
  guard let id = id else { return }
  print("Installation ID: \(id)")
}

目标-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+KTX

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 的方法已替换为删除 Firebase 安装 ID 的方法。例如:

迅速

InstanceID.instanceID().deleteID { error in
  if let error = error {
    print("Error deleting instance ID: \(error)")
  }
}

目标-C

[FIRInstanceID instanceID] deleteIDWithHandler:^(NSError *error) {
  if error != nil {
    NSLog(@"Error deleting instance ID: %@", error);
  }
}];

安卓

FirebaseInstanceId.deleteInstanceId();

迅速

func delete(completion: @escaping (Error?) -> Void)

目标-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+KTX

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+KTX

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()
        })

迅速

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)")
    self.remoteFCMTokenMessage.text = "Remote FCM registration token: \(token)"
  }
}

目标-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];
     self.remoteFCMTokenMessage.text = message;
   }
 }];

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+KTX

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()
})

迅速

Messaging.messaging().token { token, error in
  if let error = error {
    print("Error fetching FCM registration token: \(error)")
  } else if let token = token {
    print("FCM registration token: \(token)")
    self.fcmRegTokenMessage.text  = "Remote FCM registration token: \(token)"
  }
}

目标-C

[[FIRMessaging messaging] tokenWithCompletion:^(NSString *token, NSError *error) {
  if (error != nil) {
    NSLog(@"Error getting FCM registration token: %@", error);
  } else {
    NSLog(@"FCM registration token: %@", token);
    self.fcmRegTokenMessage.text = token;
  }
}];