简体   繁体   English

如何使用 web 浏览器订阅主题,使用 Firebase 云消息传递

[英]How to subscribe to topics with web browser using Firebase Cloud Messaging

I'm trying to find a way to send a notification using Firebase Cloud Messaging to all of my app's users, but I have a web-only app.我正在尝试找到一种使用 Firebase 云消息传递向我的所有应用程序用户发送通知的方法,但我有一个仅限网络的应用程序。 I've seen solutions that appear to be for Android/iOS, which basically involves having the users auto-subscribe to a topic called "allDevices" and then sending a notification to all users subscribed to that topic.我见过似乎适用于 Android/iOS 的解决方案,它基本上涉及让用户自动订阅一个名为“allDevices”的主题,然后向订阅该主题的所有用户发送通知。 I just can't seem to find any documentation on how to have a web-based user subscribe to a topic.我似乎找不到任何关于如何让基于 Web 的用户订阅主题的文档。 Does anyone know if that's possible, and if it is, is there documentation that I've missed that would cover that?有谁知道这是否可能,如果可能,是否有我错过的文档可以涵盖这一点?

Thanks谢谢

There is no direct API to subscribe clients to topics in the Firebase Cloud Messaging SDK for JavaScript. Firebase Cloud Messaging SDK for JavaScript 中没有用于为客户端订阅主题的直接 API。 Instead you can subscribe a token to a topic through the REST API.相反,您可以通过 REST API 将令牌订阅到主题。 Calling this API requires that you specify the FCM server key, which means that you should only do this on a trusted environment, such as your development machine, a server you control, or Cloud Functions.调用此 API 需要您指定 FCM 服务器密钥,这意味着您只能在受信任的环境中执行此操作,例如您的开发机器、您控制的服务器或 Cloud Functions。 This is necessary, since having the FCM server key allows sending messages on your app's behalf to all of your app's users.这是必要的,因为拥有 FCM 服务器密钥允许代表您的应用程序向所有应用程序用户发送消息。

It turns out that in my tests I was using an older project, where client API keys were allows to subscribe to topics.原来,在我的测试中,我使用的是老项目,其中客户端API密钥允许订阅主题。 This ability has been removed from newer projects for security reasons.出于安全原因,此功能已从较新的项目中删除。

In Node.js you could for example call the REST API to create a relation mapping for an app instance like this:例如,在 Node.js 中,您可以调用 REST API 为应用程序实例创建关系映射,如下所示:

function subscribeTokenToTopic(token, topic) {
  fetch('https://iid.googleapis.com/iid/v1/'+token+'/rel/topics/'+topic, {
    method: 'POST',
    headers: new Headers({
      'Authorization': 'key='+fcm_server_key
    })
  }).then(response => {
    if (response.status < 200 || response.status >= 400) {
      throw 'Error subscribing to topic: '+response.status + ' - ' + response.text();
    }
    console.log('Subscribed to "'+topic+'"');
  }).catch(error => {
    console.error(error);
  })
}

Where fcm_server_key is the FCM server key, taken from the Firebase console of your project.其中fcm_server_key是 FCM 服务器密钥,取自项目的 Firebase 控制台。

Any one looking for php solution find below since you are going to use Api key of server so don't do this on client side任何寻找 php 解决方案的人都可以在下面找到,因为您将使用服务器的 Api 密钥,所以不要在客户端执行此操作

client side fire base js code客户端火基js代码

// Initialize Firebase
var config = {
    apiKey: "xxxx",
    authDomain: "yyy",
    databaseURL: "zzzz",
    projectId: "aaaa",
    storageBucket: "bbbbb",
    messagingSenderId: "ccc"
  };
firebase.initializeApp(config);

const messaging = firebase.messaging();

messaging.requestPermission()
.then(function() {
  console.log('Notification permission granted.');
  return messaging.getToken();
})
.then(function(token) {

//send this token to server
  console.log(token); // Display user token
})
.catch(function(err) { // Happen if user deney permission

  console.log('Unable to get permission to notify.', err);
});

messaging.onMessage(function(payload){
    console.log('onMessage',payload);
})

server side code by php curl由 php curl 编写的服务器端代码

$headers = array
    ('Authorization: key=' . API_ACCESS_KEY,
    'Content-Type: application/json');

$ch = curl_init();
// browser token you can get it via ajax from client side
$token = 'drVdtCt82qY:APA91bEZb99GvoS9knv-cp5ThVBiYGBjUwl_Ewj2tKaRFwp7HoG347utaNKbgLWmkxpGadABtIg-DspPUh5sC_bc2JrBKVw10Ejg72nYxZgD2wBU-adYJo0yi03lX22s5K2UEp6gwnMv';
curl_setopt($ch, CURLOPT_URL, "https://iid.googleapis.com/iid/v1/$token/rel/topics/testIshakTopic");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POSTFIELDS, array());
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
echo "The Result : " . $result;

Hope it will help for PHP developers希望对 PHP 开发者有所帮助

Franks solution is still valid. Franks 解决方案仍然有效。 However you need to have a server that does the subscribe for you.但是,您需要有一台服务器来为您订阅。

function subscribeTokenToTopic(token, topic) {
  fetch('https://myserver.com/'+token+'/rel/topics/'+topic, {
    method: 'POST',
    headers: new Headers({
      'Authorization': 'Bearer '+ oauthToken
    })
  }).then(response => {
    if (response.status < 200 || response.status >= 400) {
      throw 'Error subscribing to topic: '+response.status + ' - ' + response.text();
    }
    console.log('Subscribed to "'+topic+'"');
  }).catch(error => {
    console.error(error);
  })
}

then your server has a rest call something like this:那么你的服务器有一个像这样的休息调用:

(java spring) (爪哇春天)

@RequestMapping(value = "/{token}/rel/topics/{topic}", method = RequestMethod.POST)
public ResponseEntity<?> subscribeTokenToTopic(@PathVariable("token") String token, @PathVariable("topic") String topic)  throws ServletException {
  URL url = new URL("https://iid.googleapis.com/iid/v1/"+token+"/rel/topics/"+topic);
  // make https post call here.. 
  ...
}

Hopefully that makes sense.希望这是有道理的。

 import firebase from 'firebase/app'; import 'firebase/messaging'; const config = { apiKey: "xxxx", authDomain: "xxx", databaseURL: "xxx", projectId: "xxx", storageBucket: "xxxx", messagingSenderId: 'xxxxx', appId: 'xxxxx', measurementId: 'xxxxxx' }; firebase.initializeApp(config); try { if (firebase.messaging.isSupported()) { const messaging = firebase.messaging(); messaging .getToken({ vapidKey: VAPID_KEY }) .then((currentToken) => { if (currentToken) { subscribeTokenToTopic(currentToken,FirebaseAdminTopic); } }) .catch((err) => { console.log('Error to get token', err); }); messaging.onMessage((payload) => { console.log(payload.notification) }); // Otherwise, we need to ask the user for permission if (Notification.permission !== 'granted') { Notification.requestPermission(); } } else { console.log('firebase messaging not supported'); } } catch (err) { console.log(err); } function subscribeTokenToTopic(token, topic) { fetch(`https://iid.googleapis.com/iid/v1/${token}/rel/topics/${topic}`, { method: 'POST', headers: new Headers({ Authorization: `key=${FCM_SERVER_KEY}` }) }) .then((response) => { if (response.status < 200 || response.status >= 400) { console.log(response.status, response); } console.log(`"${topic}" is subscribed`); }) .catch((error) => { console.error(error.result); }); return true; }

使用服务器密钥而不是 config.apiKey 工作正常。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM