【问题标题】:Firebase getIDToken and how to use it in an API callFirebase getIDToken 以及如何在 API 调用中使用它
【发布时间】:2021-04-08 20:25:01
【问题描述】:

我有一个获取 json 的 API 调用,但需要令牌身份验证。令牌身份验证效果很好,但是当我尝试将令牌传递给 API 函数时,它会返回零。我相信这是因为Auth.auth().currentUser!.getIDToken(...) 还没有真正完成。下面的相关代码...我如何将其修改为

class SessionData : ObservableObject {
    ...
    func token() -> String? {
        var result: String? = nil
        Auth.auth().currentUser!.getIDToken(completion: { (res, err) in
            if err != nil {
                print("*** TOKEN() ERROR: \(err!)")
            } else {
                print("*** TOKEN() SUCCESS: \(err!)")
                result = res!
            }
        })
       return result
    }
...
}

class FetchPosts: ObservableObject {
    @Published var posts = [Post]()
    
    func load(api: Bool, session: SessionData) {
        
        if api {
            let url = URL(string: MyAPI.getAddress(token: session.token()!))!
            URLSession.shared.dataTask(with: url) {(data, response, error) in
                do {
                    if let postsData = data {
                        // 3.
                        let decodedData = try JSONDecoder().decode(Response.self, from: postsData)
                        DispatchQueue.main.async {
                            self.posts = decodedData.result
                            if decodedData.error != nil {
                                print("ERROR: \(decodedData.error!)")
                                session.json_error(error: decodedData.error!)
                            }
                        }
                    } else {
                        print("No data. Connection error.")
                        DispatchQueue.main.async {
                            session.json_error(error: "Could not connect to server, please try again!")
                        }
                    }
                } catch {
                    print("* Error: \(error)")
                }
            }.resume()
            
        } else {
            let url = Bundle.main.url(forResource: "test", withExtension: "json")!
            let data = try! Data(contentsOf: url)
            let decoder = JSONDecoder()
            if let products = try? decoder.decode([Post].self, from: data) {
                self.posts = products
            }
        }
    }
}

这就是 .load 函数的调用方式:

UserViewer(fetch: posts)
                    .transition(AnyTransition.slide)
                    .animation(.default)
                    .onAppear {
                    
                        withAnimation{
                            posts.load(api: true, session: session)
                        }
                    }
                    .environmentObject(session)

【问题讨论】:

  • 你必须使用所谓的“回调函数”,因为它是异步完成的。

标签: swift firebase swiftui


【解决方案1】:

因为getIDToken是异步执行和返回的,所以不能直接从中返回。相反,您需要使用回调函数。

这是对你的函数的修改:

func token(_ completion: @escaping (String?) -> ()) {
            guard let user = Auth.auth().currentUser else {
                //handle error
                return
            }
            user.getIDToken(completion: { (res, err) in
                if err != nil {
                    print("*** TOKEN() ERROR: \(err!)")
                    //handle error
                } else {
                    print("*** TOKEN() SUCCESS: \(err!)")
                    completion(res)
                }
            })
        }

然后,您可以稍后使用它:

.onAppear {
  session.token { token in 
    guard let token = token else {
       //handle nil
       return 
    }
    withAnimation{
      posts.load(api: true, session: session, token: token)
    }
  }
}

修改您的load 以采用token 参数:

func load(api: Bool, session: SessionData, token: String) {
        
        if api {
            guard let url = URL(string: MyAPI.getAddress(token: token)) else {
  //handle bad URL
  return
}

另外,正如您在我的代码示例中看到的那样,我会尝试改掉使用! 强制展开选项的习惯。如果可选的是nil 而你使用!,你的程序将会崩溃。相反,请熟悉 guard letif let,并学习以不会导致崩溃的方式处理可选项——这是 Swift 的一大优势。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-03-08
    • 1970-01-01
    • 2016-02-16
    • 2018-09-18
    • 2013-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多