Scorb
Scorb

Reputation: 1920

Can I clear all my subscribed FCM topics by calling deleteToken?

I am using Firebase Cloud Messaging for Flutter.

I would like to be able to delete all the subscribed topics without my application having to store the subscribed topics itself on local storage.

Can I simple call deleteToken to unsubscribe from all topics?

Upvotes: 4

Views: 1018

Answers (2)

Jonathan Ellis
Jonathan Ellis

Reputation: 5479

As of 2024, it seems the answer is actually no. Calling deleteToken() will not unsubscribe the device from all topics (at least, not straight away).

The problem is that when you create a new token on the device, you will find that the new token is subscribed to the same topics that the old one was subscribed to.

A bit more context...

Firebase device tokens look something like:

e-c...tkk:APA...G5y_

The bit before the colon is the Firebase Installation ID (FID). What you'll find if you call deleteToken() and then create a new one soon after is that the FID is the same, even though the bit after the colon changes.

It's the FID that actually targets the device for messaging, and the FID also carries with it the topics that the device is subscribed to. So simply deleting the token and re-creating it will not unsubscribe you from all topics (you will still need to do this manually).

Getting a list of all topics an FCM token is subscribed to...

This is very poorly documented/supported, but here's some sample code (Python) for how you can list all topics that a token is subscribed to:

import json
import requests
import google.auth.transport.requests

from google.oauth2 import service_account

fcm_token = 'e-c...tkk:APA...G5y_'

credentials = service_account.Credentials.from_service_account_file(
    'path/to/service_account_key.json',
    scopes=['https://www.googleapis.com/auth/firebase.messaging']
)
request = google.auth.transport.requests.Request()
credentials.refresh(request)

url = f'https://iid.googleapis.com/iid/info/{fcm_token}?details=true'

headers = {
    'Authorization': f'Bearer {credentials.token}',
    'access_token_auth': 'true'
}

response = requests.get(url, headers=headers)

print(json.dumps(response.json(), indent=2))

Note that you'll need to generate a service account JSON key for your project.

You can use this code to check for yourself whether the new token is indeed still subscribed to the same topics as the old one.

How to solve it

The best thing is to probably just maintain a list of all topics your token is subscribed to, then make sure you unsubscribe from each of them when you want to unsubscribe from all topics (e.g. user logs out of your app).

Fortunately, the FID does not survive app reinstall, so at least you don't have to worry about that.

Apparently you can also reset the FID manually with FirebaseInstallations.getInstance().delete() after deleting your token, but I've not tried that yet!

Further reading

Upvotes: 1

Victor Eronmosele
Victor Eronmosele

Reputation: 7716

Yes, calling FirebaseMessaging.instance.deleteToken(); unsubscribes the device from all topics.

deleteToken method

Removes access to an FCM token previously authorized.

Messages sent by the server to this token will fail.

Source: deleteToken's documentation

Upvotes: 1

Related Questions