Implementierung von Push-Benachrichtigungen: Das Backend

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

Im ersten Teil dieser Serie haben wir das Frontend mit einem Service Worker, einer `manifest.json`-Datei und der Initialisierung von Firebase eingerichtet. Jetzt müssen wir unsere Datenbank und unsere Watcher-Funktionen erstellen.

Artikelserie

  1. Einrichtung & Firebase
  2. Das Backend (Sie sind hier)

Eine Datenbank erstellen

Melden Sie sich bei Firebase an und klicken Sie in der Navigation auf Database. Unter Data können Sie manuell Datenbankreferenzen hinzufügen und Änderungen in Echtzeit verfolgen.

Stellen Sie sicher, dass Sie den Regelwerk unter Rules anpassen, damit Sie während des Testens nicht mit der Authentifizierung herumfummeln müssen.

{
  "rules": {
    ".read": true,
    ".write": true
  }
}

Datenbankänderungen mit Cloud Functions beobachten

Denken Sie daran, dass der Zweck von all dem darin besteht, eine Push-Benachrichtigung zu senden, sobald Sie einen neuen Blogbeitrag veröffentlichen. Wir brauchen also eine Möglichkeit, Änderungen in den Datenzweigen zu beobachten, in denen die Beiträge gespeichert werden.

Mit Firebase Cloud Functions können wir automatisch Backend-Code ausführen, als Reaktion auf Ereignisse, die durch Firebase-Funktionen ausgelöst werden.

Firebase SDK für Cloud Functions einrichten und initialisieren

Um diese Funktionen zu erstellen, müssen wir die Firebase CLI installieren. Sie erfordert Node v6.11.1 oder höher.

npm i firebase-tools -g

Um ein Projekt zu initialisieren

  1. Führen Sie firebase login aus
  2. Authentifizieren Sie sich
  3. Wechseln Sie in Ihr Projektverzeichnis
  4. Führen Sie firebase init functions aus

Ein neuer Ordner namens `functions` wurde erstellt. Dort befindet sich eine `index.js`-Datei, in der wir unsere neuen Funktionen definieren.

Die benötigten Module importieren

Wir müssen die Module Cloud Functions und Admin SDK in `index.js` importieren und initialisieren.

const admin     = require('firebase-admin'),
      functions = require('firebase-function')

admin.initializeApp(functions.config().firebase)

Die Firebase CLI wird diese Abhängigkeiten automatisch installieren. Wenn Sie eigene hinzufügen möchten, ändern Sie `package.json`, führen Sie `npm install` aus und fordern Sie sie wie gewohnt an.

Den Watcher einrichten

Wir zielen auf die Datenbank und erstellen eine Referenz, die wir beobachten möchten. In unserem Fall speichern wir in einem posts-Zweig, der Beitrags-IDs enthält. Jedes Mal, wenn eine neue Beitrags-ID hinzugefügt oder gelöscht wird, können wir darauf reagieren.

exports.sendPostNotification = functions.database.ref('/posts/{postID}').onWrite(event => {
  // react to changes    
}

Der Name des Exports, sendPostNotification, dient dazu, alle Ihre Funktionen im Firebase-Backend zu unterscheiden.

Alle anderen Codebeispiele werden innerhalb der Funktion onWrite stattfinden.

Auf Beitrags-Löschung prüfen

Wenn ein Beitrag gelöscht wird, sollten wir wahrscheinlich keine Push-Benachrichtigung senden. Wir protokollieren also eine Nachricht und beenden die Funktion. Die Protokolle finden Sie in der Firebase-Konsole unter Functions → Logs.

Zuerst holen wir die Beitrags-ID und prüfen, ob ein Titel vorhanden ist. Wenn nicht, wurde der Beitrag gelöscht.

const postID    = event.params.postID,
      postTitle = event.data.val()

if (!postTitle) return console.log(`Post ${postID} deleted.`)

Geräte abrufen, denen Benachrichtigungen angezeigt werden sollen

Im letzten Artikel haben wir einen Geräte-Token in der Funktion updateSubscriptionOnServer in der Datenbank in einem Zweig namens device_ids gespeichert. Jetzt müssen wir diese Token abrufen, um Nachrichten an sie senden zu können. Wir erhalten sogenannte Snapshots, die im Grunde Datenreferenzen sind, die den Token enthalten.

Wenn kein Snapshot und somit kein Geräte-Token abgerufen werden konnte, protokollieren Sie eine Nachricht und beenden Sie die Funktion, da wir niemanden haben, an den wir eine Push-Benachrichtigung senden können.

const getDeviceTokensPromise = admin.database()
  .ref('device_ids')
  .once('value')
  .then(snapshots => {

      if (!snapshots) return console.log('No devices to send to.')

      // work with snapshots  
}

Die Benachrichtigungsnachricht erstellen

Wenn Snapshots verfügbar sind, müssen wir sie durchlaufen und für jeden eine Funktion ausführen, die schließlich die Benachrichtigung sendet. Aber zuerst müssen wir sie mit einem Titel, einem Text und einem Symbol füllen.

const payload = {
  notification: {
    title: `New Article: ${postTitle}`,
    body: 'Click to read article.',
    icon: 'https://mydomain.com/push-icon.png'
  }
}

snapshots.forEach(childSnapshot => {
  const token = childSnapshot.val()

  admin.messaging().sendToDevice(token, payload).then(response => {
    // handle response
  }
}

Sendeantwort verarbeiten

Falls der Versand fehlschlägt oder ein Token ungültig geworden ist, können wir ihn entfernen und eine Nachricht ausgeben.

response.results.forEach(result => {
  const error = result.error

  if (error) {
    console.error('Failed delivery to', token, error)

  if (error.code === 'messaging/invalid-registration-token' ||
      error.code === 'messaging/registration-token-not-registered') {

      childSnapshot.ref.remove()
      console.info('Was removed:', token)

  } else {
    console.info('Notification sent to', token)
  }

}

Firebase Functions bereitstellen

Um Ihre `index.js` in die Cloud hochzuladen, führen wir den folgenden Befehl aus.

firebase deploy --only functions

Fazit

Wenn Sie nun einen neuen Beitrag hinzufügen, erhalten die abonnierten Benutzer eine Push-Benachrichtigung, die sie zu Ihrem Blog zurückführt.

GitHub Repo Demo-Seite

Artikelserie

  1. Einrichtung & Firebase
  2. Das Backend (Sie sind hier)