我正在寻找一种方法,通过Firebase Cloud Messaging向我的应用程序的所有用户发送通知,但我有一个仅限Web的应用程序。我看到了一些解决方案,似乎是针对Android/iOS的,基本上涉及让用户自动订阅名为"allDevices"的主题,然后向所有订阅该主题的用户发送通知。我只是找不到有关如何使基于Web的用户订阅主题的任何文档。是否有人知道是否有可能,并且如果可以,有没有我错过的覆盖此内容的文档?
谢谢!
谢谢!
在 JavaScript 的 Firebase Cloud Messaging SDK 中,没有直接订阅客户端到主题的 API。但可以通过 REST API 将令牌订阅到主题。调用此 API 需要指定 FCM 服务器密钥,这意味着您只应在受信任的环境中执行此操作,例如开发计算机、您控制的服务器或 Cloud Functions。由于拥有 FCM 服务器密钥允许代表您的应用向所有应用程序用户发送消息,因此这是必要的。
经过我的测试发现,我使用的是旧项目,在该项目中,客户端 API 密钥可以用于订阅主题。出于安全原因,新项目已移除此功能。
例如,在 Node.js 中,您可以调用 REST API 来为应用实例创建关系映射,方法如下:create a relation mapping for an app instance
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);
})
}
其中fcm_server_key
是从您项目的Firebase控制台中获取的FCM服务器密钥。
更新:现在大多数Firebase Admin SDK也包含了将FCM令牌订阅到主题的选项,这使得在支持的环境中更容易完成此操作。有关更多信息,请参阅将客户端应用程序订阅到主题的文档。
如需 PHP 解决方案,请参考以下内容。由于您将使用服务器的 API 密钥,因此请勿在客户端执行此操作。
客户端 Firebase 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);
})
使用 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;
希望它能对PHP开发者有所帮助
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);
})
}
@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..
...
}
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可以正常工作。