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

Der*_*rek 15 javascript firebase firebase-cloud-messaging

我正在尝试使用Firebase Cloud Messaging向我的所有应用用户发送通知,但我有一个仅限网络的应用.我见过似乎适用于Android/iOS的解决方案,主要涉及让用户自动订阅名为"allDevices"的主题,然后向订阅该主题的所有用户发送通知.我似乎无法找到有关如何让基于Web的用户订阅主题的任何文档.有谁知道这是否可能,如果是的话,是否有我错过的文件会覆盖那些?

谢谢!

Fra*_*len 13

更新

通过REST API为主题订阅令牌需要服务器密钥的用户.由于拥有服务器密钥允许代表您的应用程序向所有应用程序用户发送消息,因此只能通过您控制的进程安全地完成此操作.

原来,在我的测试中,我使用的是老项目,其中客户端API密钥允许订阅主题.出于安全原因,此功能已从较新的项目中删除.

原答案如下:

您可以调用REST API来执行此操作,特别是为应用程序实例创建关系映射:

function subscribeTokenToTopic(token, topic) {
  fetch('https://iid.googleapis.com/iid/v1/'+token+'/rel/topics/'+topic, {
    method: 'POST',
    headers: new Headers({
      'Authorization': 'key='+config.apiKey
    })
  }).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);
  })
}
Run Code Online (Sandbox Code Playgroud)

configFirebase Web应用程序的配置代码段在哪里,应用程序config.apiKey公共 API密钥也是如此.

  • 您不应该*永远*在客户端代码中公开服务器密钥。在我的测试中,代码也适用于客户端 API 密钥。但我听说有传言说这是无意的,因此行为可能发生了变化。有趣的是:我刚刚测试过,我仍然可以使用 *我的* 客户端 API 密钥进行订阅,因此这种行为可能最近发生了变化,或者仅适用于较新的密钥。 (2认同)
  • 链接“https://iid.googleapis.com/iid/v1”不是 GCM 吗?它也适用于 FCM 吗? (2认同)

小智 8

任何寻找 php 解决方案的人都可以在下面找到,因为您将使用服务器的 Api 密钥,所以不要在客户端执行此操作

客户端火基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);
})
Run Code Online (Sandbox Code Playgroud)

由 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;
Run Code Online (Sandbox Code Playgroud)

希望对 PHP 开发者有所帮助


小智 6

Franks解决方案仍然有效。但是,您需要有一台为您订阅的服务器。

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);
  })
}
Run Code Online (Sandbox Code Playgroud)

那么您的服务器会有一个如下的休息电话:

(java春天)

@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.. 
  ...
}
Run Code Online (Sandbox Code Playgroud)

希望这是有道理的。


Isr*_*imu 5

    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;
        }

 
Run Code Online (Sandbox Code Playgroud)