当前位置: 首页 > 知识库问答 >
问题:

是否有权限访问用户订阅的Firebase主题?

鲁望
2023-03-14

我目前正在尝试将我的应用程序迁移到firebase,我正在寻找firebase的解析安装和通道。

我发现我们应该使用主题,但在我的应用程序中,“订阅”和“取消订阅”主题很常见,但没有办法(我发现)看到用户订阅了哪些主题。有什么想法吗?

我已经阅读了Firebase文档,但我是Firebase新手,因此可能有更多经验的人会知道:https://firebase.google.com/docs/cloud-messaging/android/topic-messaging#managing_topic_subscriptions_from_the_server

提前感谢您的帮助!

共有3个答案

戴浩初
2023-03-14

这是@Nico要求的@Eduardo's的更新

2件事:

  • 您需要导入Firebase,因为您需要InstanceID和消息传递模块
  • 确保填写API密钥(accessToken),该密钥可以在以下位置找到:(项目名称旁边的齿轮)

这是更新的代码:

import Firebase


// Grab susbcribed channels
// Source 1: https://stackoverflow.com/questions/38948720/is-there-anyway-to-access-the-firebase-topics-a-user-is-subscribed-to
// Source 2: https://developers.google.com/instance-id/reference/server#get_information_about_app_instances
extension Messaging {

// Needs to be grabbed from: https://stackoverflow.com/questions/37337512/where-can-i-find-the-api-key-for-firebase-cloud-messaging
static private let accessToken = ""

struct Topic : Decodable {
    var name : String?
    var addDate : String?
}

struct Rel : Decodable {
    var topics = [Topic]()

    init(from decoder: Decoder) throws {

        let container = try decoder.container(keyedBy: CodingKeys.self)
        let relContainer = try container.nestedContainer(keyedBy: CodingKeys.self, forKey: .rel)
        let topicsContainer = try relContainer.nestedContainer(keyedBy: CodingKeys.self, forKey: .topics )

        for key in topicsContainer.allKeys {
            var topic = Topic()
            topic.name = key.stringValue

            let topicContainer = try? topicsContainer.nestedContainer(keyedBy: CodingKeys.self, forKey: key)
            topic.addDate = try! topicContainer?.decode(String.self, forKey: .addDate)

            self.topics.append(topic)
        }
    }

    struct CodingKeys : CodingKey {
        var stringValue: String
        init?(stringValue: String) {
            self.stringValue = stringValue
        }
        var intValue: Int? { return nil }
        init?(intValue: Int) { return nil }

        static let rel = CodingKeys(stringValue: "rel")!
        static let topics = CodingKeys(stringValue: "topics")!
        static let addDate = CodingKeys(stringValue: "addDate")!
    }
}

func loadTopics(block : @escaping (_ topics: [Messaging.Topic]?, _ error: Error?) -> Void ) {
    InstanceID.instanceID().instanceID { (result, error) in
        if let err = error {
            block(nil, err)
        } else if let result = result {
            let url = URL(string: "https://iid.googleapis.com/iid/info/\(result.token)?details=true")!
            var request = URLRequest(url: url)
            request.addValue("key=\(Messaging.accessToken)", forHTTPHeaderField: "Authorization")
            let dataTask = URLSession.shared.dataTask(with: request) { (data, response, error) in
                if let data = data {
                    let decoder = JSONDecoder()
                    let rel = try? decoder.decode(Rel.self, from: data)
                    block(rel?.topics, error)
                } else {
                    block(nil, error)
                }
            }
            dataTask.resume()
        }
    }
}
}

用法是这样的:

Messaging.messaging().loadTopics { (topics, error) in
   topics?.forEach({ (topic) in
       print("Subscribed to topic: \(topic.name ?? "No name")")
   })
}
姚向晨
2023-03-14

您必须向实例ID API发出请求。我创建了一个扩展

https://gist.github.com/eduardo22i/0ee8960c36659b17fbc538964e929cac

扩展消息{

static private let accessToken = "" //Server Web Key

struct Topic : Decodable {
    var name : String?
    var addDate : String?
}

struct Rel : Decodable {
    var topics = [Topic]()

    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        let relContainer = try container.nestedContainer(keyedBy: CodingKeys.self, forKey: .rel)
        let topicsContainer = try relContainer.nestedContainer(keyedBy: CodingKeys.self, forKey: .topics )

        for key in topicsContainer.allKeys {
            var topic = Topic()
            topic.name = key.stringValue

            let topicContainer = try? topicsContainer.nestedContainer(keyedBy: CodingKeys.self, forKey: key)
            topic.addDate = try! topicContainer?.decode(String.self, forKey: .addDate)

            self.topics.append(topic)
        }
    }

    struct CodingKeys : CodingKey {
        var stringValue: String
        init?(stringValue: String) {
            self.stringValue = stringValue
        }
        var intValue: Int? { return nil }
        init?(intValue: Int) { return nil }

        static let rel = CodingKeys(stringValue: "rel")!
        static let topics = CodingKeys(stringValue: "topics")!
        static let addDate = CodingKeys(stringValue: "addDate")!
    }
}

func loadTopics(block : @escaping (_ topics: [Messaging.Topic]?, _ error: Error?) -> Void ) {
    if let token = InstanceID.instanceID().token() {
        let url = URL(string: "https://iid.googleapis.com/iid/info/\(token)?details=true")!
        var request = URLRequest(url: url)
        request.addValue("key=\(Messaging.accessToken)", forHTTPHeaderField: "Authorization")
        let dataTask = URLSession.shared.dataTask(with: request) { (data, response, error) in
        DataManager.shared.make(request: urlRequest, block: { (data, error) in
            if let data = data {
                let decoder = JSONDecoder()
                let rel = try? decoder.decode(Rel.self, from: data)
                block(rel?.topics, error)
            } else {
                block(nil, error)
            }
        }

        dataTask.resume()
    }
}
}

// Usage

Messaging.messaging().loadTopics { (topics, error) in
    topics?.forEach({ (topic) in
        print(topic.name)
    })
}
南宫正阳
2023-03-14

FCM主题订阅基于应用程序的实例ID,因此当您订阅或取消订阅主题时,会使用IID。

您可以使用实例ID API获取有关特定IID的信息,此信息包括IID当前订阅的主题。请参阅参考

 类似资料:
  • 问题内容: 我想知道是否有一种方法可以测试您是否已订阅Android方面的主题。 基本上,我 希望 所有的设备将其安装在订阅一个主题,当第一次由设备获取的令牌。但是,设备总是有可能无法订阅。FCM注册令牌应该在设备上安装很长时间,因此,在不清除数据,卸载/重新安装等情况下,不应再次调用onTokenRefresh()方法。 我的想法是测试以查看设备是否已订阅MainActivity中的主题,如果没

  • 我想知道是否有一种方法可以测试你是否订阅了android方面的主题。 基本上,我希望所有设备在安装期间,当设备首次获得令牌时,都会订阅一个主题。然而,设备总是有可能无法订阅。FCM注册令牌应该长时间安装在设备上,因此,如果不清除数据、卸载/重新安装等,就不应该再次调用onTokenRefresh()方法。 我的想法是测试设备是否订阅了我的Mainactive中的主题,如果没有,则尝试再次订阅。如果

  • 客户对主题的订阅(即订阅者)的寿命是多少? 我之所以这么担心,是因为我认为服务总线的一个特点--持久的信息。因此,我认为在连接不稳定的情况下,可以保证提供持久的消息。 那么,当一个应用程序(多个应用程序中的一个)失去与服务总线的连接一天,然后第二天重新启动应用程序并实例化一个新的订阅客户端实例时,会发生什么呢?当其他应用程序由于自己的订阅已经处理了这些相同的消息时,应用程序是否会继续接收等待传递的

  • 我试图使用create subscription API来打开一个日历事件的订阅通道,这样我们就可以在面试者对面试做出回应时收到更新。 我已经尝试了许多不同的方法来实现这个请求: 我已经完成了oauth流程,为具有以下权限范围的用户检索图形访问令牌: 使用上述范围的访问令牌,在尝试创建订阅之前,我将带有< code>{eventId}的事件添加到共享日历中,假设用户相对Id为< code>{sha

  • 问题内容: 我有几千个MySQL用户,它们都设置为允许从特定主机进行访问。问题在于,现在我将拥有两台计算机(将来将有两台计算机),它们将需要使用相同的帐户来访问他们的每个数据库。 我想要一种快速简便(尽可能自动化)的方法来运行和修改每个用户帐户的主机部分,以适合内部网络通配符。例如: ‘bugsy’@’internalfoo’可以访问’bugsy’数据库。 我现在想允许从内部网络上的任何地方进行错

  • 我正在寻找使用Azure服务总线主题发布一些消息到我的服务。我已经为我的服务创建了一个订阅,并得到了连接字符串。我的服务(WebApi)正在大量实例(1000s)上运行。我正在考虑在应用程序启动我的服务时使用连接字符串在所有实例中启动Azure Service Bus的监听器。在一个Azure服务总线订阅下运行大量的侦听器(我的服务实例)是否有问题。我很好,只有一个实例接收到消息(这实际上是我更喜