When I generate an FCM token in the browser I also send it to my server, which subscribes it to a topic with the firebase admin module like so:
messaging.subscribeToTopic(token, 'all')
I'm wondering if I delete the token in the browser using the messaging.deleteToken(currentToken) method do I also need to unsubscribe that same token using messaging.unsubscribeFromTopic(token, 'all'); on my server or does firebase do that automatically when the token is delete?
A topic subscription is really just a simple way to subscribe many ID tokens to a string. On the FCM fan-out servers that is pretty much exactly what is stored: a list of tokens associated with each topic.
Deleting a token will not really unsubscribe the token from the topic. But since the token is the only way that FCM can deliver messages to a device, messages sent to any topics the token was subscribed to can no longer be delivered (and will be cleaned up behind the scenes automatically).
Related
I am using Firebase authentication to authenticate users. Whenever, the user is logged in, I get the user's ID token with user.getIdToken(true) and set it on the local storage. With that token in the authorization header, I am requesting my back-end API.
On the back-end side, I am using Firebase admin SDK to authenticate the request and the user with the client-side ID token passed in the request authorization header.
This works for a while. But after some time I get error:
ExpiredIdTokenError: Token expired, 1620908095 < 1620915515
I saw that Firebase refreshes the ID token on its own. But I don't think that's the case. I have looked through the developer tools network tab, and there's also an observer method to check whenever the token has changed => onIdTokenChanged(), but the token is never refreshed.
I couldn't find any information on the Firebase docs either, and I was hoping if you could help me:
How can I generate a token without expiration limit to last until signed out or at least for some more time (1 week maybe)?
If I cannot the set the expiry limit of the token, what steps should I take so that I can send a valid unexpired token when I am request data from my back-end? Do I have to call user.getIdToken(true) every-time and get a fresh token before I request from my back-end API?
The idTokenChanged() observer is a bit misleading. It will fire when the token is refreshed, but the token is only refreshed automatically when you also use other Firebase products (like its database or file storage). In other cases, as you said you should call user.getIdToken(), which will refresh an expired token for you if necessary, everytime you call your API. You don't need to pass true into this method unless you want to have a completely fresh token everytime (which you most likely don't need).
To my knowledge you cannot control the expiration of tokens generated with the client SDK, for that you would need to generate your own tokens on the server.
TLDR
I am looking for somewhere to send cognito JWT's from the backend to verify the user's status.
I currently have a react app, with a serverless apollo api, and dynamodb database, all running locally.
The react client uses aws-amplify to register, sign-in etc with
aws-cognito - returning access, id and refresh tokens.
Users can also sign in with facebook and google,
amplify.Auth.federatedSignIn which returns the cognito identity
credentials.
The tokens are then passed to the backend, where they are verified.
So far I cannot find where to send the tokens from the backend, to verify that the user is signed in to cognito.
I have scoured the docs but TBH that has left me more confused.
As far as I can understand, in production API Gateway, or AppSync can intecept the tokens between the front and backend, but since I have verified tokens at the backend currently is there an endpoint or SDK method I can hit with tokens/ access keys etc to check the users status?
Feel free to tell me if I'm going about this the wrong way.
If you need to verify that a token is valid and unexpired, with the JavaScript SDK use
const cognitoServiceProvider = new AWS.CognitoIdentityServiceProvider({apiVersion: '2016-04-18'});
await cognitoServiceProvider.getUser({
AccessToken: accessToken
}).promise();
This will throw an error if the token is not valid.
If you are using a different SDK, find the equivalent call.
I have an android app that uses firebase to handle and send push notifications. When an user logs-in, it is automatically subscribed to a topic in firebase and saved the token in my database.
If after logging into the app, the users uninstall the app, their token is still in firebase, subscribed to the topic. If firebase call sendToTopic("topic"), probably will fails due this invalid token.
There is any way to get notified about those invalid tokens? I need those tokens to unsubscribe it from the topic and remove it from my database.
My end goal here is to subscribe web clients to topics in Firebase Cloud Messaging to receive simple data push events, partitioned by keys. Via this question, that seems to be possible, but only if you can send the clients' registration keys to an app server you control using the FCM Admin API: How to subscribe to topics with web browser using Firebase Cloud Messaging
Also, via https://firebase.google.com/docs/cloud-messaging/js/client, it seems to be required to request permission from the user to show desktop notifications in order to get access to the registration token for Firebase messaging.
Is there any way to tell Firebase no, I absolutely do not want desktop notifications, in fact please never show them, I just want to use data messages and never notification? And then, to get the registration token? Alternatively, is there some other way to subscribe to topics from a web client?
There is currently no other alternative to get a registration token nor is there a different way to subscribe to topics for a web client.
You already know this, but might as well mention it. Requesting permissions is a must for security purposes (preventing notifications not wanted by the user) and that in order to subscribe a web client to a topic, you'll first have to get a token (which won't generate unless the user grants permission).
Looks like you are looking for Pusher
User channel for communication. Works with out token and support bidirectional contact.
Sample code
Back End
pusher->trigger('my-channel', 'my-event', [
'message' => 'hello world'
]);
Front End
var channel = pusher.subscribe('my-channel');
channel.bind('my-event', function(data) {
alert('Received my-event with message: ' + data.message);
});
I'm currently using firebase.auth().createUserWithEmailAndPassword(email, password) to authenticate users and using the JWT token from firebase.auth().currentUser.getToken(true) for API requests. However, Firebase is invalidating the token after 1 hour. So I'm wondering how should I refresh the token. Do I have to use my own custom token generation to properly utilize token refreshing?
I'm currently using this though I only tested it once but it seems to work.
firebase.auth().onAuthStateChanged(function () { // Refresh token here })
I've been reading the docs over and over again and haven't seen any mentions of refreshing the tokens for the Web Apps. I've also looked at example repositories for firebase and have not seen anyone use onAuthStateChanged for something like this. So I'm wondering is this the right approach for client side token refresh? The reason why I feel this might not be the best approach is because this might have a race condition. For example if the token expires and I send an API request with the old token before I refresh the token then my API request will have an auth failure for token expiration.
This is very similar to the question in Firebase DB HTTP API Auth: When and how to refresh JWT token? but slightly different in the sense that the question is for using Python and no mentions of onAuthStateChanged.
Thanks!
For those who came into this post looking for an answer. You can grab the token right before all your API calls to get the token.
// Make sure you don't pass in true which will always refresh the token
firebase.auth().currentUser.getToken()
Firebase will internally determine if the token needs to be refreshed or grab from cache. If you notice Firebase will not send any network requests until the token is expired.