在 Swift 中使用 Firebase 检索 Facebook 用户图片的最佳做法是什么?

What is the best practice to retrieve Facebook user picture with Firebase in Swift?

我在 ViewModel 中使用以下方法来处理用户对 Facebook 登录按钮的点击:

import Foundation
import FirebaseAuth
import FacebookLogin

/// A view model that handles login and logout operations.
class SessionStore: ObservableObject {
    @Published var user: User?
    @Published var isAnon = false
    
    private var handle: AuthStateDidChangeListenerHandle?
    private let authRef = Auth.auth()
    
    /// A login manager for Facebook.
    private let loginManager = LoginManager()
    
    
    /// Listens to state changes made by Firebase operations.
    func listen()  {
        handle = authRef.addStateDidChangeListener {[self] (auth, user) in
            if user != nil {
                self.isAnon = false
                self.user = User(id: user!.uid, fbId: authRef.currentUser!.providerData[0].uid, name: user!.displayName!, email: user!.email!, profilePicURL: user!.photoURL)
            } else {
                self.isAnon = true
                self.user = nil
            }
        }
    }
    
    
    
    /// Logs the user in using `loginManager`.
    ///
    /// If successful, get the Facebook credential and sign in using `FirebaseAuth`.
    ///
    /// - SeeAlso: `loginManager`.
    func facebookLogin() {
       
        loginManager.logIn(permissions: [.publicProfile, .email], viewController: nil) { [self] loginResult in
            switch loginResult {
            case .failed(let error):
                print(error)
            case .cancelled:
                print("User cancelled login.")
            case .success:
                let credential = FacebookAuthProvider.credential(withAccessToken: AccessToken.current!.tokenString)
                authRef.signIn(with: credential) { (authResult, error) in
                    if let error = error {
                        print("Facebook auth with Firebase error: \(error)")
                        return
                        }
                    }
                }
            }
        }

    
}

listen() 中,每当 Firebase 检测到状态变化时(即,当用户登录时),我都会尝试构建我的 User 模型。我的 User 模型是一个简单的 struct 像这样:

/// A model for the current user.
struct User: Identifiable, Codable {
    var id: String
    var fbId: String
    var name: String
    var email: String
    var profilePicURL: URL?
}

问题

现在,正如您在我的 listen() 方法中看到的那样,我正在使用 Firebase 的 photoURL 来获取用户的个人资料图片。但是,它只会给我一张低质量的缩略图。

我很乐意从 Facebook 获取普通照片。

我试过的

我试过,在我的 facebookLogin() 中调用 GraphRequest 来获取图片 url。但是,由于我的函数是同步的,所以我无法将结果存储到我的 User 模型中。

我也试过直接使用 Graph API link 像“http://graph.facebook.com/user_id/picture?type=normal”,但它似乎是不再是 safe/suggested 做法。

问题

鉴于我的 ViewModel 结构,获取 Facebook 用户图片 URL 并将其存储到我的 User 模型的最佳方式是什么?

我发现 Firebase 的 photoURL 是 Facebook 的图表 API URL: http://graph.facebook.com/user_id/picture。因此,要获得其他尺寸,我需要做的就是将 ?type=normal 之类的查询字符串附加到 photoURL.

要使用 GraphRequest,请考虑@jnpdx 的建议:

Seems like you have at least a couple of options: 1) Use the GraphRequest and don't set your User model until you get the result back. 2) Set your User model as you are now and then update it with a new URL once your GraphRequest comes back.