Fügen Sie Empfehlungen zu Ihrer App hinzu mit TensorFlow Lite und Firebase – iOS Codelab

1. Übersicht

Willkommen beim Codelab „Empfehlungen mit TensorFlow Lite und Firebase“. In diesem Codelab erfahren Sie, wie Sie mit TensorFlow Lite und Firebase ein Empfehlungsmodell für Ihre App bereitstellen. Dieses Codelab basiert auf diesem TensorFlow Lite- Beispiel .

Empfehlungen ermöglichen es Apps, maschinelles Lernen zu nutzen, um auf intelligente Weise die relevantesten Inhalte für jeden Benutzer bereitzustellen. Sie berücksichtigen das vergangene Benutzerverhalten, um App-Inhalte vorzuschlagen, mit denen der Benutzer möglicherweise in Zukunft interagieren möchte, indem sie ein Modell verwenden, das auf das Gesamtverhalten einer großen Anzahl anderer Benutzer trainiert wurde.

Dieses Tutorial zeigt, wie Sie mit Firebase Analytics Daten von den Benutzern Ihrer App abrufen, ein maschinelles Lernmodell für Empfehlungen aus diesen Daten erstellen und dieses Modell dann in einer iOS-App verwenden, um Inferenzen auszuführen und Empfehlungen zu erhalten. Insbesondere schlagen unsere Empfehlungen vor, welche Filme ein Benutzer angesichts der Liste der Filme, die dem Benutzer zuvor gefallen haben, am wahrscheinlichsten ansehen würde.

Was Sie lernen werden

  • Integrieren Sie Firebase Analytics in eine Android-App, um Daten zum Benutzerverhalten zu sammeln
  • Exportieren Sie diese Daten in Google Big Query
  • Vorverarbeiten der Daten und Trainieren eines TF Lite-Empfehlungsmodells
  • Stellen Sie das TF Lite-Modell in Firebase ML bereit und greifen Sie über Ihre App darauf zu
  • Ausführung auf Geräteinferenz mithilfe des Modells, um Benutzern Empfehlungen vorzuschlagen

Was du brauchen wirst

  • Xcode 11 (oder höher)
  • CocoaPods 1.9.1 (oder höher)

Wie werden Sie dieses Tutorial verwenden?

Nur durchlesen Lies es und vervollständige die Übungen

Wie würden Sie Ihre Erfahrung mit dem Erstellen von iOS-Apps bewerten?

Anfänger Dazwischenliegend Kompetent

2. Erstellen Sie ein Firebase-Konsolenprojekt

Fügen Sie dem Projekt Firebase hinzu

  1. Gehen Sie zur Firebase-Konsole .
  2. Wählen Sie „ Neues Projekt erstellen“ und nennen Sie Ihr Projekt „Firebase ML iOS Codelab“.

3. Holen Sie sich das Beispielprojekt

Laden Sie den Code herunter

Beginnen Sie mit dem Klonen des Beispielprojekts und dem Ausführen von pod update im Projektverzeichnis:

git clone https://github.com/FirebaseExtended/codelab-contentrecommendations-ios.git
cd codelab-contentrecommendations-ios/start
pod install --repo-update

Wenn Sie Git nicht installiert haben, können Sie das Beispielprojekt auch von der GitHub-Seite herunterladen oder auf diesen Link klicken. Nachdem Sie das Projekt heruntergeladen haben, führen Sie es in Xcode aus und spielen Sie mit der Empfehlung herum, um ein Gefühl dafür zu bekommen, wie es funktioniert.

Firebase einrichten

Folgen Sie der Dokumentation , um ein neues Firebase-Projekt zu erstellen. Nachdem Sie Ihr Projekt erstellt haben, laden Sie die Datei GoogleService-Info.plist Ihres Projekts von der Firebase-Konsole herunter und ziehen Sie sie in das Stammverzeichnis des Xcode-Projekts.

4a923d5c7ae0d8f3.png

Fügen Sie Ihrer Pod-Datei Firebase hinzu und führen Sie die Pod-Installation aus.

pod 'Firebase/Analytics'
pod 'Firebase/MLCommon'
pod 'Firebase/MLModelInterpreter'

Importieren Sie in der Methode didFinishLaunchingWithOptions Ihres AppDelegate Firebase am Anfang der Datei

import Firebase

Und fügen Sie einen Aufruf hinzu, um Firebase zu konfigurieren.

FirebaseApp.configure()

Führen Sie das Projekt erneut aus, um sicherzustellen, dass die App richtig konfiguriert ist und beim Start nicht abstürzt.

  1. Stellen Sie sicher, dass „Google Analytics für dieses Projekt aktivieren“ aktiviert ist.
  2. Befolgen Sie die verbleibenden Einrichtungsschritte in der Firebase-Konsole und klicken Sie dann auf Projekt erstellen (oder Firebase hinzufügen, wenn Sie ein vorhandenes Google-Projekt verwenden).

4. Fügen Sie der App Firebase Analytics hinzu

In diesem Schritt fügen Sie der App Firebase Analytics hinzu, um Daten zum Benutzerverhalten zu protokollieren (in diesem Fall, welche Filme einem Benutzer gefallen). Diese Daten werden in zukünftigen Schritten aggregiert verwendet, um das Empfehlungsmodell zu trainieren.

Richten Sie Firebase Analytics in der App ein

Das LikedMoviesViewModel enthält Funktionen zum Speichern der Filme, die dem Benutzer gefallen. Jedes Mal, wenn dem Benutzer ein neuer Film gefällt, möchten wir auch ein Analyseprotokollereignis senden, um dieses Like aufzuzeichnen.

Fügen Sie den folgenden Code hinzu, um ein Analyseereignis zu registrieren, wenn der Benutzer wie auf einen Film klickt.

AllMoviesCollectionViewController.swift

import Firebase
//


override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
//

if movie.liked == nil {
      movie.liked = true
      Analytics.logEvent(AnalyticsEventSelectItem, parameters: [AnalyticsParameterItemID: movie.id])
    } else {
      movie.liked?.toggle()
    }
       
}

5. Testen Sie Ihre Analytics-Integration

In diesem Schritt generieren wir Analytics-Ereignisse in der App und überprüfen, ob sie an die Firebase-Konsole gesendet werden.

Aktivieren Sie die Analytics-Debug-Protokollierung

Im Allgemeinen werden von Ihrer App protokollierte Ereignisse über einen Zeitraum von etwa einer Stunde zusammengefasst und zusammen hochgeladen. Dieser Ansatz schont den Akku auf den Geräten der Endbenutzer und reduziert die Netzwerkdatennutzung. Um Ihre Analyseimplementierung zu validieren (und um Ihre Analyse im DebugView-Bericht anzuzeigen), können Sie jedoch den Debug-Modus auf Ihrem Entwicklungsgerät aktivieren, um Ereignisse mit minimaler Verzögerung hochzuladen.

Um den Analytics-Debug-Modus auf Ihrem Entwicklungsgerät zu aktivieren, geben Sie das folgende Befehlszeilenargument in Xcode an:

-FIRDebugEnabled

An diesem Punkt haben Sie Firebase Analytics erfolgreich in Ihre App integriert. Wenn Benutzer Ihre App verwenden und Filme mögen, werden ihre Likes aggregiert protokolliert. Wir werden diese aggregierten Daten im Rest dieses Codelabs verwenden, um unser Empfehlungsmodell zu trainieren. Der folgende Schritt ist optional, damit dieselben Analytics-Ereignisse, die Sie in Logcat gesehen haben, auch in die Firebase-Konsole gestreamt werden. Fühlen Sie sich frei, zur nächsten Seite zu springen.

Optional: Bestätigen Sie Analytics-Ereignisse in der Firebase Console

  1. Gehen Sie zur Firebase-Konsole .
  2. Wählen Sie DebugView unter Analytics aus
  3. Wählen Sie in Xcode Ausführen aus, um die App zu starten und einige Filme zu Ihrer „Gefällt mir“-Liste hinzuzufügen.
  4. Überprüfen Sie in der DebugView der Firebase-Konsole, ob diese Ereignisse protokolliert werden, wenn Sie Filme in der App hinzufügen.

6. Exportieren Sie Analytics-Daten nach Big Query

Big Query ist ein Google Cloud-Produkt, mit dem Sie große Datenmengen untersuchen und verarbeiten können. In diesem Schritt verbinden Sie Ihr Firebase Console-Projekt mit Big Query, sodass die von Ihrer App generierten Analytics-Daten automatisch nach Big Query exportiert werden.

Big Query-Export aktivieren

  1. Gehen Sie zur Firebase-Konsole .
  2. Wählen Sie das Zahnradsymbol Einstellungen neben Projektübersicht und dann Projekteinstellungen aus
  3. Wählen Sie die Registerkarte Integrationen aus.
  4. Wählen Sie im BigQuery- Block Link (oder Manage ) aus.
  5. Wählen Sie im Schritt Über das Verknüpfen von Firebase mit BigQuery die Option Weiter aus .
  6. Klicken Sie im Abschnitt Integration konfigurieren auf den Schalter, um das Senden von Google Analytics-Daten zu aktivieren, und wählen Sie Mit BigQuery verknüpfen aus .

Sie haben Ihr Firebase-Konsolenprojekt jetzt aktiviert, um Firebase Analytics-Ereignisdaten automatisch an Big Query zu senden. Dies geschieht automatisch ohne weitere Interaktion, der erste Export, der das Analyse-Dataset in BigQuery erstellt, erfolgt jedoch möglicherweise erst nach 24 Stunden. Nachdem das Dataset erstellt wurde, exportiert Firebase kontinuierlich neue Analytics-Ereignisse nach Big Query in die Intraday-Tabelle und gruppiert Ereignisse vergangener Tage in der Ereignistabelle.

Für das Training eines Empfehlungsmodells sind viele Daten erforderlich. Da wir noch keine App haben, die große Datenmengen generiert, importieren wir im nächsten Schritt ein Beispiel-Dataset in BigQuery, um es für den Rest dieser Anleitung zu verwenden.

7. Verwenden Sie BigQuery, um Modelltrainingsdaten abzurufen

Nachdem wir unsere Firebase-Konsole für den Export nach BigQuery verbunden haben, werden unsere Anwendungsanalyse-Ereignisdaten nach einiger Zeit automatisch in der BigQuery-Konsole angezeigt. Um einige Anfangsdaten für die Zwecke dieser Anleitung zu erhalten, importieren wir in diesem Schritt ein vorhandenes Beispiel-Dataset in Ihre BigQuery-Konsole, um es zum Trainieren unseres Empfehlungsmodells zu verwenden.

Beispiel-Dataset in BigQuery importieren

  1. Rufen Sie das BigQuery- Dashboard in der Google Cloud-Konsole auf.
  2. Wählen Sie im Menü Ihren Projektnamen aus.
  3. Wählen Sie Ihren Projektnamen unten in der linken BigQuery-Navigation aus, um Details anzuzeigen.
  4. Wählen Sie Datensatz erstellen aus, um das Fenster zur Datensatzerstellung zu öffnen.
  5. Geben Sie als Datensatz- ID „firebase_recommendations_dataset“ ein und wählen Sie Datensatz erstellen aus.
  6. Der neue Datensatz wird im linken Menü unter dem Projektnamen angezeigt. Klick es.
  7. Wählen Sie Tabelle erstellen aus, um das Tabellenerstellungsfenster zu öffnen.
  8. Wählen Sie für Tabelle erstellen aus „Google Cloud Storage“ aus.
  9. Geben Sie im Feld Datei aus GCS-Bucket auswählen „gs://firebase-recommendations/recommendations-test/formatted_data_filtered.txt“ ein.
  10. Wählen Sie „JSONL“ im Dropdown-Menü „ Dateiformat “ aus.
  11. Geben Sie „recommendations_table“ als Tabellennamen ein .
  12. Aktivieren Sie das Kontrollkästchen unter Schema > Automatische Erkennung > Schema und Eingabeparameter
  13. Wählen Sie Tabelle erstellen aus

Erkunden Sie den Beispieldatensatz

An dieser Stelle können Sie optional das Schema untersuchen und dieses Dataset in der Vorschau anzeigen.

  1. Wählen Sie im linken Menü firebase-recommendations-dataset aus, um die darin enthaltenen Tabellen zu erweitern.
  2. Wählen Sie die Tabelle Recommendations-Table aus, um das Tabellenschema anzuzeigen.
  3. Wählen Sie Vorschau aus, um die tatsächlichen Analytics-Ereignisdaten anzuzeigen, die diese Tabelle enthält.

Anmeldedaten für das Dienstkonto erstellen

Jetzt erstellen wir in unserem Google Cloud-Konsolenprojekt Anmeldeinformationen für Dienstkonten, die wir im folgenden Schritt in der Colab-Umgebung verwenden können, um auf unsere BigQuery-Daten zuzugreifen und sie zu laden.

  1. Stellen Sie sicher, dass die Abrechnung für Ihr Google Cloud-Projekt aktiviert ist.
  2. Aktivieren Sie die APIs BigQuery und BigQuery Storage API. < hier klicken >
  3. Rufen Sie die Seite Dienstkontoschlüssel erstellen auf.
  4. Wählen Sie in der Liste Dienstkonto die Option Neues Dienstkonto aus .
  5. Geben Sie im Feld Dienstkontoname einen Namen ein.
  6. Wählen Sie in der Rollenliste Projekt > Eigentümer aus.
  7. Klicken Sie auf Erstellen . Eine JSON-Datei, die Ihre Schlüsseldownloads auf Ihren Computer enthält.

Im nächsten Schritt werden wir Google Colab verwenden, um diese Daten vorzuverarbeiten und unser Empfehlungsmodell zu trainieren.

8. Daten vorverarbeiten und Empfehlungsmodell trainieren

In diesem Schritt verwenden wir ein Colab-Notebook, um die folgenden Schritte auszuführen:

  1. Importieren Sie die BigQuery-Daten in das Colab-Notebook
  2. die Daten vorverarbeiten, um sie für das Modelltraining vorzubereiten
  3. Trainieren Sie das Empfehlungsmodell anhand der Analysedaten
  4. Exportieren Sie das Modell als TF-Lite-Modell
  5. Stellen Sie das Modell in der Firebase-Konsole bereit, damit wir es in unserer App verwenden können

Bevor wir das Colab-Schulungsnotebook starten, aktivieren wir zunächst die Firebase Model Management API, damit Colab das trainierte Modell auf unserer Firebase-Konsole bereitstellen kann.

Aktivieren Sie die Firebase Model Management API

Erstellen Sie einen Bucket zum Speichern Ihrer ML-Modelle

Gehen Sie in Ihrer Firebase-Konsole zu Speicher und klicken Sie auf Erste Schritte. fbbea78f0eb3dc9f.png

Folgen Sie dem Dialog, um Ihren Bucket einzurichten.

19517c0d6d2aa14d.png

Aktivieren Sie die Firebase ML-API

Gehen Sie in der Google Cloud Console zur Firebase ML API-Seite und klicken Sie auf Aktivieren.

Verwenden Sie das Colab-Notebook, um das Modell zu trainieren und bereitzustellen

Öffnen Sie das Colab-Notebook über den folgenden Link und führen Sie die darin enthaltenen Schritte aus. Nachdem Sie die Schritte im Colab-Notizbuch abgeschlossen haben, wird eine TF-Lite-Modelldatei auf der Firebase-Konsole bereitgestellt, die wir mit unserer App synchronisieren können.

In Colab öffnen

9. Laden Sie das Modell in Ihrer App herunter

In diesem Schritt ändern wir unsere App, um das Modell herunterzuladen, das wir gerade von Firebase Machine Learning trainiert haben.

Firebase ML-Abhängigkeit hinzufügen

Die folgende Abhängigkeit ist erforderlich, um Firebase Machine Learning-Modelle in Ihrer App zu verwenden. Es sollte bereits hinzugefügt werden (überprüfen).

Podfile

import Firebase

Laden Sie das Modell mit der Firebase Model Manager API herunter

Kopieren Sie den folgenden Code in ModelDownloader.swift , um die Bedingungen festzulegen, unter denen der Modelldownload erfolgt, und erstellen Sie eine Download-Aufgabe, um das Remote-Modell mit unserer App zu synchronisieren.

ModelDownloader.swift

  static func downloadModel(named name: String,
                            completion: @escaping (RemoteModel?,         DownloadError?) -> Void) {
    guard FirebaseApp.app() != nil else {
      completion(nil, .firebaseNotInitialized)
      return
    }
    guard success == nil && failure == nil else {
      completion(nil, .downloadInProgress)
      return
    }

    let remoteModel = CustomRemoteModel(name: name)
    let conditions = ModelDownloadConditions(allowsCellularAccess: true,
                                             allowsBackgroundDownloading: true)

    success = NotificationCenter.default.addObserver(forName: .firebaseMLModelDownloadDidSucceed,
                                                     object: nil,
                                                     queue: nil) { (notification) in
      defer { success = nil; failure = nil }
      guard let userInfo = notification.userInfo,
          let model = userInfo[ModelDownloadUserInfoKey.remoteModel.rawValue] as? RemoteModel
      else {
        completion(nil, .downloadReturnedEmptyModel)
        return
      }
      guard model.name == name else {
        completion(nil, .downloadReturnedWrongModel)
        return
      }
      completion(model, nil)
    }
    failure = NotificationCenter.default.addObserver(forName: .firebaseMLModelDownloadDidFail,
                                                     object: nil,
                                                     queue: nil) { (notification) in
      defer { success = nil; failure = nil }
      guard let userInfo = notification.userInfo,
          let error = userInfo[ModelDownloadUserInfoKey.error.rawValue] as? Error
      else {
        completion(nil, .mlkitError(underlyingError: DownloadError.unknownError))
        return
      }
      completion(nil, .mlkitError(underlyingError: error))
    }
    ModelManager.modelManager().download(remoteModel, conditions: conditions)
  }

ModelDownloader.swift

  static func fetchModel(named name: String,
                         completion: @escaping (String?, DownloadError?) -> Void) {
    let remoteModel = CustomRemoteModel(name: name)
    if ModelManager.modelManager().isModelDownloaded(remoteModel) {
      ModelManager.modelManager().getLatestModelFilePath(remoteModel) { (path, error) in
        completion(path, error.map { DownloadError.mlkitError(underlyingError: $0) })
      }
    } else {
      downloadModel(named: name) { (model, error) in
        guard let model = model else {
          let underlyingError = error ?? DownloadError.unknownError
          let compositeError = DownloadError.mlkitError(underlyingError: underlyingError)
          completion(nil, compositeError)
          return
        }
        ModelManager.modelManager().getLatestModelFilePath(model) { (path, pathError) in
          completion(path, error.map { DownloadError.mlkitError(underlyingError: $0) })
        }
      }
    }
  }

10. Integrieren Sie das Empfehlungsmodell von Tensorflow Lite in Ihre App

Mit der Tensorflow Lite-Laufzeit können Sie Ihr Modell in der App verwenden, um Empfehlungen zu generieren. Im vorherigen Schritt haben wir einen TFlite-Interpreter mit der heruntergeladenen Modelldatei initialisiert. In diesem Schritt laden wir zuerst ein Wörterbuch und Beschriftungen, um unser Modell im Inferenzschritt zu begleiten, dann fügen wir eine Vorverarbeitung hinzu, um die Eingaben für unser Modell zu generieren, und eine Nachverarbeitung, bei der wir die Ergebnisse aus unserer Inferenz extrahieren .

Wörterbuch und Labels laden

Die Bezeichnungen, die zum Generieren der Empfehlungskandidaten durch das Empfehlungsmodell verwendet werden, sind in der Datei sorted_movie_vocab.json im Assets-Ordner aufgeführt. Kopieren Sie den folgenden Code, um diese Kandidaten zu laden.

RecommendationsViewController.swift

  func getMovies() -> [MovieItem] {
    let barController = self.tabBarController as! TabBarController
    return barController.movies
  }

Implementieren Sie die Vorverarbeitung

Im Vorverarbeitungsschritt ändern wir die Form der Eingabedaten, damit sie mit den Erwartungen unseres Modells übereinstimmen. Hier füllen wir die Eingabelänge mit einem Platzhalterwert auf, falls wir noch nicht viele User-Likes generiert haben. Kopieren Sie den folgenden Code:

RecommendationsViewController.swift

  // Given a list of selected items, preprocess to get tflite input.
  func preProcess() -> Data {
    let likedMovies = getLikedMovies().map { (MovieItem) -> Int32 in
      return MovieItem.id
    }
    var inputData = Data(copyingBufferOf: Array(likedMovies.prefix(10)))

    // Pad input data to have a minimum of 10 context items (4 bytes each)
    while inputData.count < 10*4 {
      inputData.append(0)
    }
    return inputData
  }

Führen Sie den Interpreter aus, um Empfehlungen zu generieren

Hier verwenden wir das Modell, das wir in einem vorherigen Schritt heruntergeladen haben, um Rückschlüsse auf unsere vorverarbeitete Eingabe zu ziehen. Wir legen die Art der Ein- und Ausgabe für unser Modell fest und führen Inferenzen aus, um unsere Filmempfehlungen zu generieren. Kopieren Sie den folgenden Code in Ihre App.

RecommendationsViewController.swift

import TensorFlowLite

RecommendationsViewController.swift

 private var interpreter: Interpreter?

 func loadModel() {
    // Download the model from Firebase
    print("Fetching recommendations model...")
    ModelDownloader.fetchModel(named: "recommendations") { (filePath, error) in
      guard let path = filePath else {
        if let error = error {
          print(error)
        }
        return
      }
      print("Recommendations model download complete")
      self.loadInterpreter(path: path)
    }
  }

 func loadInterpreter(path: String) {
    do {
      interpreter = try Interpreter(modelPath: path)

      // Allocate memory for the model's input `Tensor`s.
      try interpreter?.allocateTensors()

      let inputData = preProcess()

      // Copy the input data to the input `Tensor`.
      try self.interpreter?.copy(inputData, toInputAt: 0)

      // Run inference by invoking the `Interpreter`.
      try self.interpreter?.invoke()

      // Get the output `Tensor`
      let confidenceOutputTensor = try self.interpreter?.output(at: 0)
      let idOutputTensor = try self.interpreter?.output(at: 1)

      // Copy output to `Data` to process the inference results.
      let confidenceOutputSize = confidenceOutputTensor?.shape.dimensions.reduce(1, {x, y in x * y})

      let idOutputSize = idOutputTensor?.shape.dimensions.reduce(1, {x, y in x * y})

      let confidenceResults =
        UnsafeMutableBufferPointer<Float32>.allocate(capacity: confidenceOutputSize!)
      let idResults =
        UnsafeMutableBufferPointer<Int32>.allocate(capacity: idOutputSize!)
      _ = confidenceOutputTensor?.data.copyBytes(to: confidenceResults)
      _ = idOutputTensor?.data.copyBytes(to: idResults)

      postProcess(idResults, confidenceResults)

      print("Successfully ran inference")
      DispatchQueue.main.async {
        self.tableView.reloadData()
      }
    } catch {
      print("Error occurred creating model interpreter: \(error)")
    }
  }

Implementieren Sie die Nachbearbeitung

Schließlich verarbeiten wir in diesem Schritt die Ausgabe unseres Modells nach, wählen die Ergebnisse mit der höchsten Zuverlässigkeit aus und entfernen enthaltene Werte (Filme, die dem Benutzer bereits gefallen haben). Kopieren Sie den folgenden Code in Ihre App.

RecommendationsViewController.swift

  // Postprocess to get results from tflite inference.
  func postProcess(_ idResults: UnsafeMutableBufferPointer<Int32>, _ confidenceResults: UnsafeMutableBufferPointer<Float32>) {
    for i in 0..<10 {
      let id = idResults[i]
      let movieIdx = getMovies().firstIndex { $0.id == id }
      let title = getMovies()[movieIdx!].title
      recommendations.append(Recommendation(title: title, confidence: confidenceResults[i]))
    }
  }

Testen Sie Ihre Anwendung!

Führen Sie Ihre App erneut aus. Wenn Sie einige Filme auswählen, sollte das neue Modell automatisch heruntergeladen und Empfehlungen generiert werden!

11. Herzlichen Glückwunsch!

Sie haben mithilfe von TensorFlow Lite und Firebase eine Empfehlungsfunktion in Ihre App integriert. Beachten Sie, dass die in diesem Codelab gezeigten Techniken und Pipelines verallgemeinert und auch für andere Arten von Empfehlungen verwendet werden können.

Was wir abgedeckt haben

  • Firebase ML
  • Firebase-Analytics
  • Exportieren Sie Analyseereignisse nach BigQuery
  • Analyseereignisse vorverarbeiten
  • Zugempfehlungen TensorFlow-Modell
  • Modell exportieren und in Firebase Console bereitstellen
  • Servieren Sie Filmempfehlungen in einer App

Nächste Schritte

  • Implementieren Sie Firebase ML-Empfehlungen in Ihrer App.

Lern mehr

Eine Frage haben?

Probleme melden