我正在尝试找到一种使用 Firebase Cloud Messaging 向我的应用程序的所有用户发送通知的方法,但我有一个仅限网络的应用程序。我见过似乎适用于 Android/iOS 的解决方案,这基本上涉及让用户自动订阅名为“allDevices”的主题,然后向订阅该主题的所有用户发送通知。我似乎找不到任何关于如何让基于 Web 的用户订阅主题的文档。有谁知道这是否可能,如果可能,是否有我遗漏的文档可以涵盖这一点?
谢谢!
我正在尝试找到一种使用 Firebase Cloud Messaging 向我的应用程序的所有用户发送通知的方法,但我有一个仅限网络的应用程序。我见过似乎适用于 Android/iOS 的解决方案,这基本上涉及让用户自动订阅名为“allDevices”的主题,然后向订阅该主题的所有用户发送通知。我似乎找不到任何关于如何让基于 Web 的用户订阅主题的文档。有谁知道这是否可能,如果可能,是否有我遗漏的文档可以涵盖这一点?
谢谢!
Firebase Cloud Messaging SDK for JavaScript 中没有用于为客户端订阅主题的直接 API。相反,您可以通过 REST API 将令牌订阅到主题。调用此 API 需要您指定 FCM 服务器密钥,这意味着您只能在受信任的环境中执行此操作,例如您的开发机器、您控制的服务器或 Cloud Functions。这是必要的,因为拥有 FCM 服务器密钥允许代表您的应用程序向所有应用程序用户发送消息。
原来,在我的测试中,我使用的是老项目,其中客户端API密钥都允许订阅主题。出于安全原因,此功能已从较新的项目中删除。
例如,在 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);
})
}
fcm_server_key
从项目的 Firebase 控制台获取的 FCM 服务器密钥在哪里。
任何寻找 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);
})
由 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 开发者有所帮助
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);
})
}
那么你的服务器有一个像这样的休息调用:
(JavaSpring)
@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 工作正常。