Ajoutez des étiquettes sécurisées aux images avec Cloud Vision à l'aide de Firebase Auth et de Functions sur les plates-formes Apple

Pour appeler une API Google Cloud depuis votre application, vous devez créer une API REST intermédiaire qui gère l'autorisation et protège les valeurs secrètes telles que les clés API. Vous devez ensuite écrire du code dans votre application mobile pour vous authentifier auprès de ce service intermédiaire et communiquer avec lui.

Vous pouvez créer cette API REST à l'aide de Firebase Authentication et de Firebase Functions, qui vous offrent une passerelle sans serveur gérée vers les API Google Cloud. Cette passerelle gère l'authentification et peut être appelée depuis votre application mobile à l'aide de SDK prédéfinis.

Ce guide explique comment utiliser cette technique pour appeler l'API Cloud Vision depuis votre application. Cette méthode permet à tous les utilisateurs authentifiés d'accéder aux services payants de Cloud Vision via votre projet Cloud. Avant de continuer, vérifiez si ce mécanisme d'authentification est suffisant pour votre cas d'utilisation.

Avant de commencer

Configurez votre projet

Si vous n'avez pas encore ajouté Firebase à votre application, suivez les étapes du guide de démarrage.

Utilisez Swift Package Manager pour installer et gérer les dépendances Firebase.

  1. Dans Xcode, à partir de votre projet d’application ouvert, accédez à File > Add Packages.
  2. Lorsque vous y êtes invité, ajoutez le dépôt du SDK des plates-formes Firebase pour Apple :
  3.   https://github.com/firebase/firebase-ios-sdk.git
  4. Choisissez la bibliothèque Firebase ML.
  5. Ajoutez l'indicateur -ObjC à la section Other Linker Flags (Autres indicateurs Linker) des paramètres de compilation de votre cible.
  6. Lorsque vous avez terminé, Xcode commence à résoudre et à télécharger automatiquement vos dépendances en arrière-plan.

Ensuite, effectuez une configuration dans l'application :

  1. Dans votre application, importez Firebase :

    Swift

    import FirebaseMLModelDownloader

    Objective-C

    @import FirebaseMLModelDownloader;

Il ne reste plus que quelques étapes de configuration :

  1. Si vous n'avez pas encore activé les API basées sur le cloud pour votre projet, faites-le maintenant :

    1. Ouvrez la Firebase ML page API dans la Firebase console.
    2. Si vous n'avez pas encore mis à niveau votre projet vers le forfait Blaze avec paiement à l'usage, cliquez sur Upgrade (Mettre à niveau). (Vous serez invité à effectuer la mise à niveau uniquement si votre projet n'est pas associé au forfait Blaze.)

      Seuls les projets associés au forfait Blaze peuvent utiliser les API basées sur le cloud.

    3. Si les API basées sur le cloud ne sont pas encore activées, cliquez sur Enable Cloud-based APIs (Activer les API basées sur le cloud).
  2. Configurez vos clés API Firebase existantes pour interdire l'accès à l'API Cloud Vision :
    1. Ouvrez la page Identifiants de la console Cloud.
    2. Pour chaque clé API de la liste, ouvrez la vue d'édition, puis, dans la section "Key Restrictions" (Restrictions de clé), ajoutez toutes les API disponibles à l'exception de l'API Cloud Vision API à la liste.

Déployer la fonction appelable

Ensuite, déployez la fonction Cloud que vous utiliserez pour connecter votre application et l'API Cloud Vision. Le dépôt functions-samples contient un exemple que vous pouvez utiliser.

Par défaut, l'accès à l'API Cloud Vision via cette fonction n'autorise que les utilisateurs authentifiés de votre application à accéder à l'API Cloud Vision. Vous pouvez modifier la fonction pour répondre à différents besoins.

Pour déployer la fonction, procédez comme suit :

  1. Clonez ou téléchargez le dépôt functions-samples , puis accédez au répertoire Node-1st-gen/vision-annotate-image :
    git clone https://github.com/firebase/functions-samples
    cd Node-1st-gen/vision-annotate-image
    
  2. Installez les dépendances :
    cd functions
    npm install
    cd ..
  3. Si vous ne disposez pas de la CLI Firebase, installez-la.
  4. Initialisez un projet Firebase dans le vision-annotate-image répertoire. Lorsque vous y êtes invité, sélectionnez votre projet dans la liste.
    firebase init
  5. Déployez la fonction :
    firebase deploy --only functions:annotateImage

Ajouter Firebase Auth à votre application

La fonction appelable déployée ci-dessus refusera toute requête provenant d'utilisateurs non authentifiés de votre application. Si ce n'est pas déjà fait, vous devez ajouter Firebase Auth à votre application.

Ajouter les dépendances nécessaires à votre application

Utilisez Swift Package Manager pour installer la bibliothèque Cloud Functions for Firebase.

Vous êtes maintenant prêt à libeller des images.

1. Préparer l'image d'entrée

Pour appeler Cloud Vision, l'image doit être mise en forme sous forme de chaîne encodée en base64. Pour traiter un UIImage :

Swift

guard let imageData = uiImage.jpegData(compressionQuality: 1.0) else { return }
let base64encodedImage = imageData.base64EncodedString()

Objective-C

NSData *imageData = UIImageJPEGRepresentation(uiImage, 1.0f);
NSString *base64encodedImage =
  [imageData base64EncodedStringWithOptions:NSDataBase64Encoding76CharacterLineLength];

2. Appeler la fonction appelable pour libeller l'image

Pour libeller des objets dans une image, appelez la fonction appelable en transmettant une requête Cloud Vision JSON.

  1. Commencez par initialiser une instance de Cloud Functions :

    Swift

    lazy var functions = Functions.functions()
    

    Objective-C

    @property(strong, nonatomic) FIRFunctions *functions;
    
  2. Créez une requête dont le type est défini sur LABEL_DETECTION :

    Swift

    let requestData = [
      "image": ["content": base64encodedImage],
      "features": ["maxResults": 5, "type": "LABEL_DETECTION"]
    ]
    

    Objective-C

    NSDictionary *requestData = @{
      @"image": @{@"content": base64encodedImage},
      @"features": @{@"maxResults": @5, @"type": @"LABEL_DETECTION"}
    };
    
  3. Enfin, appelez la fonction :

    Swift

    do {
      let result = try await functions.httpsCallable("annotateImage").call(requestData)
      print(result)
    } catch {
      if let error = error as NSError? {
        if error.domain == FunctionsErrorDomain {
          let code = FunctionsErrorCode(rawValue: error.code)
          let message = error.localizedDescription
          let details = error.userInfo[FunctionsErrorDetailsKey]
        }
        // ...
      }
    }
    

    Objective-C

    [[_functions HTTPSCallableWithName:@"annotateImage"]
                              callWithObject:requestData
                                  completion:^(FIRHTTPSCallableResult * _Nullable result, NSError * _Nullable error) {
            if (error) {
              if ([error.domain isEqualToString:@"com.firebase.functions"]) {
                FIRFunctionsErrorCode code = error.code;
                NSString *message = error.localizedDescription;
                NSObject *details = error.userInfo[@"details"];
              }
              // ...
            }
            // Function completed succesfully
            // Get information about labeled objects
    
          }];
    

3. Obtenir des informations sur les objets libellés

Si l'opération de libellisation d'image réussit, une réponse JSON de BatchAnnotateImagesResponse est renvoyée dans le résultat de la tâche. Chaque objet du tableau labelAnnotations représente un élément libellé dans l'image. Pour chaque libellé, vous pouvez obtenir sa description textuelle, son ID d'entité Knowledge Graph (le cas échéant) et le score de confiance de la correspondance. Exemple :

Swift

if let labelArray = (result?.data as? [String: Any])?["labelAnnotations"] as? [[String:Any]] {
  for labelObj in labelArray {
    let text = labelObj["description"]
    let entityId = labelObj["mid"]
    let confidence = labelObj["score"]
  }
}

Objective-C

NSArray *labelArray = result.data[@"labelAnnotations"];
for (NSDictionary *labelObj in labelArray) {
  NSString *text = labelObj[@"description"];
  NSString *entityId = labelObj[@"mid"];
  NSNumber *confidence = labelObj[@"score"];
}