5

I'm using Firebase on iOS and am trying to implement Topics. I know how to subscribe and unsubscribe:

Messaging.messaging().subscribe(toTopic: "myTopic")

Messaging.messaging().unsubscribe(fromTopic: "myTopic")

My question is, how do I know what topics I am subscribed to? How do I unsubscribe to all topics I am subscribed to? How do I access all topics from Firebase?

KENdi
  • 7,576
  • 2
  • 16
  • 31
user7097242
  • 1,034
  • 3
  • 16
  • 31
  • 1
    This is a question about Android, but the process is the same: https://stackoverflow.com/questions/37987821/get-all-subscribed-topics-from-firebase-cloud-messaging – dalton_c Sep 14 '17 at 22:27
  • Check my answer maybe it helps: https://stackoverflow.com/questions/39623742/firebase-cloud-messaging-check-existing-or-available-topics/47835917#47835917 – Eduardo Irias Dec 15 '17 at 16:03

1 Answers1

0

I managed to do it in iOS by sending a GET request to https://iid.googleapis.com/iid/info :

Models for decoding response:

struct AppInstance: Codable {
    let applicationVersion: String
    let gmiRegistrationId: String
    let application: String
    let scope: String
    let authorizedEntity: String
    let rel: Rel
    let platform: String
}

struct Rel: Codable {
    let topics: [String: AddDate]
    
    enum CodingKeys: String, CodingKey {
        case topics
    }
    
    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        topics = try container.decode([String: AddDate].self, forKey: .topics)
    }
}

struct AddDate: Codable {
    let addDate: String
}

Then called the following function:

func getSubscribedTopics() async -> [String]? {
    let fcmToken = "YOUR_FCM_TOKEN" // received inside didReceiveRegistrationToken callback

    guard var urlComponents = URLComponents(string: "https://iid.googleapis.com/iid/info/\(fcmToken)")
        else { return nil }

    let parameter = URLQueryItem(name: "details", value: "true")
    urlComponents.queryItems = [parameter]

    guard let url = urlComponents.url else { return nil }
        
    let serverKey = "YOUR_SERVER_KEY" // from firebase console
    var request = URLRequest(url: url)
    request.httpMethod = "GET"
    request.addValue("Bearer \(serverKey)", forHTTPHeaderField: "Authorization") // this will be deprecated

    let (data, _) = try! await URLSession.shared.data(for: request)
    let decoder = JSONDecoder()
    let appInstance = try! decoder.decode(AppInstance.self, from: data)
    let topics = appInstance.rel.topics.keys.map { $0 as String }
    return topics
}

This is currently working but using the server key for authorization will be deprecated in June 2024. I should replace the server key with a token but this didn't work with me and the server responded with "Unauthorized".

Tony
  • 716
  • 9
  • 15