【问题标题】:Assign username value from firestore从 firestore 分配用户名值
【发布时间】:2019-07-07 03:04:15
【问题描述】:

我正在创建我的第一个应用程序(以及 swift 中的新手)。当我从 Facebook 登录时,姓名和电子邮件保存在 Firestore 中。我正在尝试将 facebook 中的名称设置为变量以在其他地方使用它,但我无法分配值,始终在控制台中显示“nil”。谁能帮帮我?

  1. 我设置了变量
var userN: String?
  1. 我从 Firestore 获取数据
func readDatabase(){

    let db = Firestore.firestore()
    let docRef = db.collection("users").document("email")


    docRef.getDocument { (document, error) in
        if let document = document, document.exists {
            let dataDescription = document.data().map(String.init(describing:)) ?? "nil"
            print("Document data: \(dataDescription)")

            let data = document.data()

            let userName = data!["name"]! as! String
            print(userName)

            let userEmail = data!["email"]! as! String
            print(userEmail)

let containerController = ContainerController()
            let containerController.userN = userName;
            return
        }
    }

}

我想分配userN = userName,以便在其他视图中使用它 我怎样才能做到这一点?谢谢

【问题讨论】:

  • 欢迎来到 SO,有几件事。首先,将其他用户信息存储在 Firestore 中的 /users 集合中,但使用用户 uid 作为 documentId,而不是电子邮件。将 documentId 与其包含的数据分离通常是最佳实践,特别是如果您要使用的 id 是动态的(可能会更改),例如电子邮件地址; uid 是静态的。接下来是Firestore is asynchronous,请仔细阅读;你不应该同步调用它并尝试返回一个值。
  • 另外,document.data().map(String.init(describing:)) ??读取 Firestore 中的字段不需要“nil”。这就是它在文档中的显示方式,但我认为您在上下文中使用它(并且该文档不是很清楚 IMO)。如果您可以包含对您的 Firestore 结构的描述,我将向您展示如何做到这一点。
  • 您好,感谢您的建议。好吧,我正在使用电子邮件,因为我正在测试 firebase 连接,但将来我将使用你所说的 uid。我正在使用 document.data() 因为 firebase 助手说,我是新手。我的 Firestore 的结构有一个“用户”集合,在其中,我有字段设备、用户名、电子邮件和照片 url,从谷歌或 Facebook 登录中检索。我只想在变量中设置这个字段,以便在我的菜单视图中使用它,并显示登录用户的信息。

标签: swift firebase variables google-cloud-firestore variable-assignment


【解决方案1】:

如果你使用 StoryBoards,你可以通过 segue 函数传递它;

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "YourStoryBoardSegue" {
            if let viewController = segue.destination as? ContainerController {
                viewController.userN = userName
            }    
        }
   }

否则,最佳做法是使用委托方法。

在堆栈溢出中搜索使用委托传递数据的最佳实践。

【讨论】:

  • 我没有使用故事板。你能给我一个使用委托的例子吗?
  • @jhonhlc 虽然这是一段漂亮的代码,但它与您的问题无关。您的 userName 将继续为零,因为 userName 在关闭之外无效。在尝试将任何内容传递给另一个控制器之前,您需要先解决这个问题。
  • @jhonhlc 虽然委托模式是一个强大的工具,但在这种情况下不需要它,而且绝对不是“最佳实践”只是 在其他地方使用它作为您的问题状态。事实上,除非您将数据传回视图控制器,否则根本不需要它。因为您使用的是实时更新的 Firebase,您可能会发现您很少将数据传回。阅读this question 和很好的答案以获取更多信息。
  • 嗨@jay,正如我在问题中所说,我是新来的,我不知道该怎么做。我想将登录视图中的信息传递到我的菜单视图并显示登录用户的信息。我必须对我的代码进行哪些更改以改进它,并使用来自 firestore 的数据声明一个 var?
【解决方案2】:

这个问题非常广泛,在不了解细节的情况下,解决它的唯一方法是提供一个通用答案,专门解决如何从 Firestore 读取数据并将其保存在一个变量中以供以后使用。

假设您的 Firestore 看起来像这样

root
   users
      uid_0
         name: "users name"
      uid_1
         name: "another users name"

当应用加载时,我们希望根据您的问题读取用户名并将其存储在一个变量中:

在其他地方使用的变量

这就是它的样子

class ViewController: NSViewController {

    var usersName = ""

    override func viewDidLoad() {
        super.viewDidLoad()
        FirebaseApp.configure()
        self.db = Firestore.firestore()
        let settings = self.db.settings
        self.db.settings = settings
        self.readUserName()
    }

    func readUsersName() {
        let users = self.db.collection("users")
        let thisUser = users.document("uid_1")
        thisUser.getDocument(completion: { documentSnapshot, error in
            if let error = error {
                print(error.localizedDescription)
                return
            }
            let name = documentSnapshot?.get("name") as! String
            self.usersName = name
        })
    }

代码设置 Firestore,从 uid_1 文档中读取用户名并将其存储在一个变量中,供以后使用。

假设我们想让用户更改他们的名字。有 100 种方法可以做到;通过 segue 传递数据,使用委托方法或打开详细视图控制器,在它关闭之前,让这个主控制器从 textField 读取更新的名称并保存数据。您甚至可以传递用户 uid,然后在详细视图控制器中通过该 uid 读取文档,然后在关闭时更新它。但是,所有这些都超出了问题的范围。

【讨论】:

    猜你喜欢
    • 2022-01-21
    • 1970-01-01
    • 1970-01-01
    • 2011-08-07
    • 2021-01-18
    • 2020-12-04
    • 1970-01-01
    • 1970-01-01
    • 2019-01-16
    相关资源
    最近更新 更多