2017-05-01 181 views
2

我已成功地建立火力雲功能發送通知的主題。問題是它發送給包括髮件人在內的所有用戶,我如何設置我的雲端功能,以便它不會向發件人顯示通知?請幫忙?下面是我如何發送主題Android的火力地堡雲功能通知

exports.sendNotesNotification = functions.database.ref('/Notes/{pushId}') 
    .onWrite(event => { 
     const notes = event.data.val(); 

     const payload = { 
       notification: { 

        username: notes.username, 
        title: notes.title, 
        body: notes.desc 

       } 

      } 

      admin.messaging().sendToTopic("New_entry", payload) 
      .then(function(response){ 
       console.log("Successfully sent notes: ", response); 
      }) 
      .catch(function(error){ 
       console.log("Error sending notes: ", error); 
      }); 
     }); 
+0

您必須知道發送者的FCM ID。當你發送給所有人時,只需檢查並排除發件人的fcm ID,然後發送通知 –

+0

,請顯示nodejs的新代碼示例。 –

回答

6

從火力的文檔,使用主題發送通知應該是公開和時間並不重要通知來完成。在你的情況下,通知不公開,並且由於發件人也訂閱了該特定主題,所以他也將收到通知。 因此,如果您想避免向發件人發送通知,則必須從您的主題中取消訂閱該發件人。

或者更好的解決辦法是,你應該使用發送FCM有令牌通知單個設備。 發送通知FCM令牌Node.js的代碼是

admin.messaging().sendToDevice(<array of tokens>, payload); 

,你可以從你的onTokenRefresh Android的FirebaseInstanceIdService()方法獲取設備的令牌。

@Override 
    public void onTokenRefresh() { 
     // Get updated InstanceID token. 
     String refreshedToken = FirebaseInstanceId.getInstance().getToken(); 
     // TO DO: send token to your server or firebase database 
} 

更新:

要保存火力令牌到你的數據庫現在,你應該構建數據庫,這樣

-users 
     |-user1uid 
     | |-name //your choice 
     | |-email //your choice 
     | |-fcmTokens 
     |  |-valueOftoken1:true 
     |  |-valueOftoken2:true 
    -notes 
     | |-notesId 
     |  |-yourdata 
     |  |-createdBy:uidofUser //user who created note 
     | 
    -subscriptions  //when onWrite() will trigger we will use this to get UID of all subscribers of creator of "note". 
     |  |-uidofUser  
     |   |-uidofSubscriber1:true //user subscribe to notes written. by parent node uid 
     |   |-uidofSubscriber2:true 

保存在數據庫這裏的令牌是onTokenRefresh()代碼

@Override 
     public void onTokenRefresh() { 
      // Get updated InstanceID token. 
      String refreshedToken = FirebaseInstanceId.getInstance().getToken(); //get refreshed token 
      FirebaseAuth mAuth = FirebaseAuth.getInstance(); 
      FirebaseUser user = mAuth.getCurrentUser(); //get currentto get uid 
      if(user!=null){ 
      DatabaseReference mDatabase = FirebaseDatabase.getInstance().getReference().child("users").child(user.getUid()); // create a reference to userUid in database 
      if(refreshedToken!=null) // 
       mDatabase.child("fcmTokens").child(refreshedToken).setValue(true); //creates a new node of user's token and set its value to true. 
      else 
       Log.i(TAG, "onTokenRefresh: token was null"); 
    } 
    Log.d(tag, "Refreshed token SEND TO FIREBASE: " + refreshedToken); 
    } 

whe爲此用戶創建了一個永久的新令牌,上面的代碼將在用戶的fcmTokens中創建新的節點。

這裏來獲取用戶令牌和發送通知這些令牌的Node.js的一部分。 此

exports.sendNotesNotification = functions.database.ref('/Notes/{pushId}') 
    .onWrite(event => { 

     const notes = event.data.val(); 
     const createdby = notes.createdBy; 
     const getAllSubscribersPromise = admin.database().ref(`/subscriptions/${createdby}/`).once('value'); // retrieving subscribers 

     const payload = { 
       notification: { 

        username: notes.username, 
        title: notes.title, 
        body: notes.desc 

       } 

      } 

     return getAllSubscribersPromise.then(result => { 
     const userUidSnapShot = result; //results will have children having keys of subscribers uid. 
     if (!userUidSnapShot.hasChildren()) { 
      return console.log('There are no subscribed users to write notifications.'); 
     } 
     console.log('There are', userUidSnapShot.numChildren(), 'users to send notifications to.'); 
     const users = Object.keys(userUidSnapShot.val()); //fetched the keys creating array of subscribed users 

     var AllFollowersFCMPromises = []; //create new array of promises of TokenList for every subscribed users 
     for (var i = 0;i<userUidSnapShot.numChildren(); i++) { 
      const user=users[i]; 
      console.log('getting promise of user uid=',user); 
      AllFollowersFCMPromises[i]= admin.database().ref(`/users/${user}/fcmToken/`).once('value'); 
     } 

     return Promise.all(AllFollowersFCMPromises).then(results => { 

      var tokens = []; // here is created array of tokens now ill add all the fcm tokens of all the user and then send notification to all these. 
      for(var i in results){ 
       var usersTokenSnapShot=results[i]; 
       console.log('For user = ',i); 
       if(usersTokenSnapShot.exists()){ 
        if (usersTokenSnapShot.hasChildren()) { 
         const t= Object.keys(usersTokenSnapShot.val()); //array of all tokens of user [n] 
         tokens = tokens.concat(t); //adding all tokens of user to token array 
         console.log('token[s] of user = ',t); 
        } 
        else{ 

        } 
       } 
      } 
      console.log('final tokens = ',tokens," notification= ",payload); 
      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 uid=', tokens[index], error); 
         // Cleanup the tokens who are not registered anymore. 
         if (error.code === 'messaging/invalid-registration-token' || error.code === 'messaging/registration-token-not-registered') { 
          tokensToRemove.push(usersTokenSnapShot.ref.child(tokens[index]).remove()); 
         } 
        } 
        else{ 
         console.log("notification sent",result); 
        } 
       }); 

       return Promise.all(tokensToRemove); 
      }); 

      return console.log('final tokens = ',tokens," notification= ",payload); 
     }); 





      }); 
     }); 

我沒有檢查Node.js的部分讓我知道如果你仍然有問題。

+0

謝謝,看起來不錯會給它一個嘗試,但我也可以使用數組的uid或我只需要使用令牌? –

+0

我的代碼也出現此錯誤錯誤:解析函數觸發器時發生錯誤。 C:\用戶\德克斯特\應用程序數據\本地\ TEMP \ fbfn_11128qrnTKRceWFWR \ index.js:64 admin.messaging()sendToDevice(<令牌的陣列>,有效載荷) ^ –

+1

否則不能使用UID發送通知到設備。我們有1個用戶有2個設備或有時用戶FCM令牌發生變化的情況(例如,如果用戶刪除應用程序數據)。每次它獲得一個新的值,包括第一次在android中調用'onTokenRefresh()'方法,這就是爲什麼我們實現我們的邏輯來發送FCM令牌到'onTokenRefresh()'方法內的服務器/數據庫。 –