0

私の雑誌のアプリケーションでは、Firebaseサービスを使用しています。このAndroidアプリケーションの1つの機能は、新しい記事が公開されるたびに新しい記事がすべてのデバイス。登録されているすべてのデバイスに通知を送信するためのメッセージング

私はこのようなDB内のすべてのデバイストークンを保存しています: FCMToken { ユーザーID:deviceToken }

を新しいノードがfirebaseデシベルで「公表」キーに追加されるたびので、FCM機能がトリガされると、メッセージは、すべてのデバイスに送信されます。

以下

は、FCMの機能のためにJavaScriptで私のコードです:

'use strict' 
const functions = require('firebase-functions'); 
const admin = require('firebase-admin'); 
admin.initializeApp(functions.config().firebase); 
exports.sendNotification = functions.database.ref('/published/{msg_id}').onWrite(event => { 
    const snapshot = event.data; 
    // Only send a notification when a new message has been created. 
    if (snapshot.previous.val()) { 
    return; 
    } 
    const msg_id = event.params.msg_id; 

    const msg_val=admin.database().ref(`messages/${msg_id}`).once('value'); 
    return msg_val.then(msgResult =>{ 
    const msg_title=msgResult.val().title; 
    const user_id=msgResult.val().userId; 
    console.log('msg title is',msg_title); 
    console.log('We have a new article : ', msg_id); 
     const payload={ 

     data : { 
      title:"New Article", 
      body: msg_title, 
      msgid : msg_id, 
      userid : user_id 

     } 
    }; 


// const deviceToken = admin.database().ref('/FCMToken/{user_id}').once('value'); 
admin.database().ref('/FCMToken').on("value", function(dbsnapshot) 
{ 
    dbsnapshot.forEach(function(childSnapshot) { 
    //var childKey = childSnapshot.key; 
    const childData = childSnapshot.val(); 
    const deviceToken=console.log("device token" + childSnapshot.val()); 


    return admin.messaging().sendToDevice(childData,payload).then(response=>{ 
     console.log("This was notification feature") 
     console.log("response: ", response); 
    }) 
    .catch(function(error) 
    { 
     console.log("error sending message",error) 
    }); 
    }); 
    }); 

    }); 

}); 

何らかの理由で、通知があります1つのデバイス(FCMノードの最初のトークン)にのみ送信されます。 更新: 私は自分のコードを更新して約束を使用していますが、何らかの理由でまだ動作していないので、最初のデバイストークンに通知を送信します。

'use strict' 
const functions = require('firebase-functions'); 
const admin = require('firebase-admin'); 
admin.initializeApp(functions.config().firebase); 
exports.sendNotification = functions.database.ref('/published/{msg_id}').onWrite(event => { 
    const snapshot = event.data; 
    // Only send a notification when a new message has been created. 
    if (snapshot.previous.val()) { 
    return; 
    } 
    const msg_id = event.params.msg_id; 

    const msg_val=admin.database().ref(`messages/${msg_id}`).once('value'); 
    return msg_val.then(msgResult =>{ 
    const msg_title=msgResult.val().title; 
    const user_id=msgResult.val().userId; 
    console.log('msg title is',msg_title); 
    console.log('We have a new article : ', msg_id); 
     const payload={ 

     data : { 
      title:"New Article", 
      body: msg_title, 
      msgid : msg_id, 
      userid : user_id 

     } 
    }; 

const promises=[]; 

// const deviceToken = admin.database().ref('/FCMToken/{user_id}').once('value'); 
admin.database().ref('/FCMToken').once('value').then(function(dbsnapshot) 
{ 

    dbsnapshot.forEach(function(childSnapshot) { 
    //var childKey = childSnapshot.key; 
    const childData = childSnapshot.val(); 
    const deviceToken=console.log("device token" + childSnapshot.val()); 


    const promise = admin.messaging().sendToDevice(childData,payload).then(response=>{ 
    promises.push(promise) 
     console.log("This was notification feature") 
     console.log("response: ", response); 
    }) 
    return Promise.all(promises) 
    .catch(function(error) 
    { 
     console.log("error sending message",error) 
    }); 
    }); 
    }); 

    }); 

}); 

Responseオブジェクトは、この出力を与えている:応答:{結果:{エラー:[オブジェクト]}]、 canonicalRegistrationTokenCount:0、 failureCount:1、 successCount:0、 multicastId:6411440389982586000}

+0

すべてのデバイスのFCMトークンを使用して送信することは、特定のトピックをサブスクライブするようにして、通知を送信代わりに。より効率的になります。 – kunwar97

答えて

0

あなたは、あなたの機能を通して約束を正しく使用していません。 2つのことが間違っています。

まず、あなたが代わりにon()once()を使用してデータベースを照会し、作業の次の項目に進むためには、それから返さ約束使用する必要があります。また

admin.database().ref('/FCMToken').on("value") 
.then(result => /* continue your work here */) 

を、あなたは返すことはできませんforEachループからの約束。代わりに、関数の最後のステップとして、関数の最上位レベルで約束を返す必要があります。この約束は、この機能ですべての作業が行われたときに解決する必要があります。あなたの機能にとって、これはすべてのメッセージが送信されたときを意味します。配列内のすべてのメッセージのすべての約束を集めて、それらがすべて解決されたときに解決する単一の約束を返す必要があります。

const promises = [] 

dbsnapshot.forEach(function(childSnapshot) { 
    // remember each promise for each message sent 
    const promise = return admin.messaging().sendToDevice(...) 
    promises.push(promise) 
}) 

// return a single promise that resolves when everything is done 
return Promise.all(promises) 

約束事がJavaScriptでどのように機能するかを学ぶために注意してください。約束事を正しく処理せずに効果的な機能を書くことはできません。

+0

ありがとうございました。 – user3792429

+0

こんにちは!私は私の機能を更新しましたが、問題は同じままです: – user3792429

0

私は値を取得する別の方法を考え出しました。 const tokens = Object.keys(tokensSnapshot.val())。map(e => tokensSnapshot.val()[e]);

以下は私の完全な方法である:

'use strict' 
const functions = require('firebase-functions'); 
const admin = require('firebase-admin'); 
//Object.values = require('object.values'); 
admin.initializeApp(functions.config().firebase); 
exports.sendNotification = functions.database.ref('/published/{msg_id}').onWrite(event => { 
    const snapshot = event.data; 
    // Only send a notification when a new message has been created. 
    if (snapshot.previous.val()) { 
    return; 
    } 
    const msg_id = event.params.msg_id; 

    const msg_val=admin.database().ref(`messages/${msg_id}`).once('value'); 
    return msg_val.then(msgResult =>{ 
    const msg_title=msgResult.val().title; 
    const user_id=msgResult.val().userId; 
    console.log('msg title is',msg_title); 
    console.log('We have a new article : ', msg_id); 
     const payload={ 

     data : { 
      title:"New Article", 
      body: msg_title, 
      msgid : msg_id, 
      userid : user_id 

     } 
    }; 




const getDeviceTokensPromise = admin.database().ref('/FCMToken').once('value'); 
return Promise.all([getDeviceTokensPromise, msg_title]).then(results => { 


    const tokensSnapshot = results[0]; 
    const msgi = results[1]; 

    if (!tokensSnapshot.hasChildren()) { 
     return console.log('There are no notification tokens to send to.'); 
    } 
    console.log('There are', tokensSnapshot.numChildren(), 'tokens to send notifications to.'); 
    console.log("tokenslist",tokensSnapshot.val()); 
    const tokens= Object.keys(tokensSnapshot.val()).map(e => tokensSnapshot.val()[e]); 
    //var values = Object.keys(o).map(e => obj[e]) 


    return admin.messaging().sendToDevice(tokens, payload).then(response => { 
     // For each message check if there was an error. 
     const tokensToRemove = []; 
     response.results.forEach((result, index) => { 
     const error = result.error; 
     if (error) { 
      console.error('Failure sending notification to', tokens[index], error); 
      // Cleanup the tokens who are not registered anymore. 

     } 
     }); 
     return Promise.all(tokensToRemove); 
    }); 

}); 
}); 
}); 
関連する問題