簡體   English   中英

Firebase雲功能和Android推送通知

[英]Firebase Cloud Functions and Android Push Notification

我遇到了這個問題,我正在創建一個連接到Firebase的android應用程序。 然后,我將Raspberry Pi連接到Firebase,從Pi發送的數據是GPS坐標,特別是緯度和經度。 當Firebase上的數據已更改或主節點上的坐標已更改時,我要創建的主應用程序具有“推送通知”功能。 這是我的Firebase數據的屏幕截圖:

Firebase數據庫屏幕截圖

我的問題是,我創建的雲函數發現了我不理解的錯誤,或者我正在對其進行監督。 我在Firebase文檔中查找了文章中的示例代碼,但我想似乎沒有什么適合我。 這是雲函數的代碼,以及我在Firebase中手動輸入數據時遇到的錯誤。

const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);

exports.sendLocationNotification = functions.database.ref("/GPS/{gps_id}").onWrite((event)=>{

var latitude = event.data.child('latitude'); 

var longitude = event.data.child('longitude');        

if(!latitude.changed() && !longitude.changed()){

return console.log('The database has been reset');
    } 

const payload = {        
    notification:{            
            title: "Location Monitor",            
            body: "Your motorcycle has moved",            
            icon: "default",            
            sound: "default"
        }
    };


    const options = {        
            priority: "high",
            timeToLive: 60 * 60 * 24
    };

        return admin.messaging().sendToTopic("Location_Notification", payload, options)

});

下一個是Android應用程序,即使我的Firebase FCM位於gradle:app中,我還是在Firebase控制台中手動發送了一條消息,該應用程序在隨該應用程序安裝的avd或手機上未收到任何消息。 這是我的MessagingService處理前台通知的代碼:

import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.media.RingtoneManager;
import android.net.Uri;
import android.support.v4.app.NotificationCompat;
import android.util.Log;

import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;

import java.util.Map;

public class MyFirebaseMessagingService extends FirebaseMessagingService {

    private static final String TAG = "FirebaseMessgingService";

    @Override

    public void onMessageReceived(RemoteMessage remoteMessage){

        if(remoteMessage.getData().size()>0){
            Map<String, String> payload = remoteMessage.getData();

            showNotification(payload);

        }

    }

    private void showNotification(Map<String, String> payload) {

        Intent intent = new Intent(this, Tracking.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        PendingIntent pendingIntent = PendingIntent.getActivity(this,0,intent, PendingIntent.FLAG_ONE_SHOT);

        Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
        NotificationCompat.Builder notificationBuilder = (NotificationCompat.Builder) new NotificationCompat.Builder(this)
                .setAutoCancel(true)
                .setSmallIcon(R.drawable.track)
                .setContentIntent(pendingIntent)
                .setContentTitle(payload.get("Title"))
                .setContentText(payload.get("Body"))
                .setSound(defaultSoundUri);

        NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.notify(0,notificationBuilder.build());

    }

}

然后這是我的android清單:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="">

    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".Splash">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".Menu" />
        <!--
             The API key for Google Maps-based APIs is defined as a string resource.
             (See the file "res/values/google_maps_api.xml").
             Note that the API key is linked to the encryption key used to sign the APK.
             You need a different API key for each encryption key, including the release key that is used to
             sign the APK for publishing.
             You can define the keys for the debug and release targets in src/debug/ and src/release/. 
        -->
        <meta-data
            android:name="com.google.android.geo.API_KEY"
            android:value="@string/google_maps_key" />
        <meta-data
            android:name="com.google.firebase.messaging.default_notification_icon"
            android:resource="@drawable/track"/>
        <service android:name=".MyFirebaseMessagingService">
            <intent-filter>
                <action android:name="com.google.firebase.MESSAGING_EVENT"/>
            </intent-filter>
        </service>
        <activity
            android:name=".Tracking"
            android:label="@string/title_activity_tracking" />
        <activity
            android:name=".Tracing"
            android:label="@string/title_activity_tracing" />
        <activity android:name=".Tips" />
        <activity android:name=".Instruction" />
        <activity android:name=".About"></activity>
    </application>

</manifest>

這是我的gradle:app

apply plugin: 'com.android.application'

android {
    compileSdkVersion 26
    defaultConfig {
        applicationId ""
        minSdkVersion 15
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:26.1.0'
    implementation 'com.android.support.constraint:constraint-layout:1.0.2'
    implementation 'com.google.android.gms:play-services-maps:11.0.4'
    implementation 'com.google.firebase:firebase-database:11.0.4'
    implementation 'com.google.firebase:firebase-messaging:11.0.4'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.1'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
    compile 'com.github.Hitomis:CircleMenu:v1.1.0'
}


apply plugin: 'com.google.gms.google-services'

這是一個不斷出現的錯誤:

TypeError: Cannot read property 'child' of undefined
    at exports.sendLocationNotification.functions.database.ref.onWrite (/user_code/index.js:13:30)
    at Object.<anonymous> (/user_code/node_modules/firebase-functions/lib/cloud-functions.js:112:27)
    at next (native)
    at /user_code/node_modules/firebase-functions/lib/cloud-functions.js:28:71
    at __awaiter (/user_code/node_modules/firebase-functions/lib/cloud-functions.js:24:12)
    at cloudFunction (/user_code/node_modules/firebase-functions/lib/cloud-functions.js:82:36)
    at /var/tmp/worker/worker.js:700:26
    at process._tickDomainCallback (internal/process/next_tick.js:135:7)

根據Firebase有關onWrite方法的文檔,它已通過:

一個functions.Change含有非空functions.database.DataSnapshot和一個可選的非空functions.EventContext

但是,在您的函數中,您需要一個事件對象,該事件對象為空。

按照此處提供的示例代碼,您可以像這樣重新編寫函數:

exports.makeUppercase = functions.database.ref("/GPS/{gps_id}")
    .onWrite((change, context) => {

      // You can get the previous value for latitude and longitude
      var previousLatitude = change.before.ref.parent.child('latitude'); 
      var previousLongitude = change.before.ref.parent.child('longitude');

      // And the new values
      var newLatitude = change.after.ref.parent.child('latitude'); 
      var newLongitude = change.after.ref.parent.child('longitude');

      // And perform your logic from here
      ...

      return admin.messaging().sendToTopic("Location_Notification", payload, options);
    });

我沒有檢查過您提到的Android問題,但是我猜想由於Firebase Function失敗,所以return語句沒有執行,也沒有任何通知發送。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM