通知不会显示在数据库触发器上

问题描述:

我正在使用firebase云功能向数据库触发器调用时向用户发送通知。注册令牌保存在firebase数据库中。问题是,尽管注册令牌得到了保存,通知并未显示在这些设备中。 这是index.js通知不会显示在数据库触发器上

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



exports.sendNotification = functions.database.ref('/Blog').onWrite(event => { 
const title = event.data.child('title').val(); 

const token_no = event.data.child('token_no').val(); 


    const getDeviceTokensPromise = admin.database().ref(`/Token/${token_no}`).once('value'); 
    const getBody=admin.database().ref(`/Blog`).once('value'); 

    return Promise.all([getDeviceTokensPromise,getBody]).then(results => { 
    const tokensSnapshot = results[0]; 
    const notify=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.'); 


    // Notification details. 
    const payload = { 
     notification: { 
     title: 'You have a new Alert!', 
     body: `${notify.child('title').val()}`, 

     } 
    }; 

    // Listing all tokens. 
    const tokens = Object.keys(tokensSnapshot.val()); 

    // Send notifications to all tokens. 
    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. 
      if (error.code === 'messaging/invalid-registration-token' || 
       error.code === 'messaging/registration-token-not-registered') { 
      tokensToRemove.push(tokensSnapshot.ref.child(tokens[index]).remove()); 
      } 
     } 
     }); 
     return Promise.all(tokensToRemove); 
    }); 
    }); 
}); 

数据库快照:

"Token" : { 
"token_no" : { 
    "ctxjePemYZE:APA91bFJXXyTkyvXOlSY...4VbWu7Vbf7itwbwZu9umSvg_tdB1lKD1d8g" : "true", 
    "dgVszInjIW0:APA91bFZE3Av5unZTgp...RUeYb-CUhWjO1otqguhE9NTQZ8XgK6nRIW5" : "true" 
} 

}

更新2:

代码使用Object.keys(tokensSnapshot.val())拿到令牌。这意味着令牌必须是token_no下的密钥,而不是值。就像这样:

"Token" : { 
    "-KoWsMn9rCIitQeNvixr" : { 
    "dK1FjGbNr6k:APA91b...S8JK2d69JpO" : "123" // token is the key, value is not significant; could be "123", true, or 0. 
    }, 
    ... 
} 

更新:

您应该查看数据库触发器的documentation for the Event parameter,以获得更好的理解paramsdata属性。 params为触发器引用中的通配符提供访问权限,data是快照。在你的代码中,你想从快照中获取值。

添加这些变化:

const title = event.data.child('title').val(); 
const desp = event.data.child('desp').val(); 
const token_no = event.data.child('token_no').val() 

const payload = { 
    notification: { 
    title: 'You have a new Alert!', 
    body: `${Post.child('title').val()}`, // <= CHANGED 
    //icon: follower.photoURL 
    } 
}; 

运行您发布的代码,这些变化,我能够发送和接收通知。

有两个问题。第一个是这样的陈述:

const getDeviceTokensPromise = admin.database().ref(`/Token/{token_no}`).once('value'); 

token_no没有定义。然后,当你定义它,想取代它的价值,你将需要添加一个$

`/Token/${token_no}` 

的第二个问题是,Post没有定义,这将导致函数执行失败。检查你的功能日志:

const payload = { 
    notification: { 
    title: 'You have a new Alert!', 
    body: `${Post.title}`, 
    //icon: follower.photoURL 
    } 
}; 
+0

你可以请检查代码是否正确,因为我对JavaScript有一点了解。在运行编辑好的代码后,它也会被执行,但是云功能的日志会显示“没有通知令牌要发送给”。 ,但令牌正在保存在数据库中。我不确定代码出错的地方。 –

+0

它仍然是一样的!它仍然在日志中显示没有令牌。我们必须创建FirebaseInstanceId来生成令牌,对吧?或者index.js会自动执行它? –

+0

应用程序的每个实例都必须使用(例如)FirebaseInstanceId.getInstance()。getToken()来存储它的标记并将其存储在数据库中。 –