Firebase getIDToken 以及如何在 API 调用中使用它

Posted

技术标签:

【中文标题】Firebase getIDToken 以及如何在 API 调用中使用它【英文标题】:Firebase getIDToken and how to use it in an API call 【发布时间】: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)

【问题讨论】:

你必须使用所谓的“回调函数”,因为它是异步完成的。 【参考方案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 的一大优势。

【讨论】:

以上是关于Firebase getIDToken 以及如何在 API 调用中使用它的主要内容,如果未能解决你的问题,请参考以下文章

Firebase getIdToken() + React Native + 刷新用户数据库以验证电子邮件验证用户

Firebase 令牌在 1 小时内过期后如何保留用户?

如何从 firebase_auth 获取令牌

同步获取Firebase用户令牌

如何从 "getFirebase().auth().currentUser.getIdToken() "中获取字符串值。

如何处理 Firebase 中过期的用户 ID 令牌?