如果无法从 Firebase 实时数据库中检索数据,则尝试在 UITableView 上显示消息

Posted

技术标签:

【中文标题】如果无法从 Firebase 实时数据库中检索数据,则尝试在 UITableView 上显示消息【英文标题】:Trying to display a message on UITableView if data cannot be retrieved from Firebase Real Time Database 【发布时间】:2020-06-24 17:15:22 【问题描述】:

背景

我目前正在我的 ios 应用程序中构建任务管理器功能。用户可以为一周中的每一天添加/完成任务。

当用户在某一天添加​​任务时,会引用该特定日期,并且该任务会在 Firebase RTD 中列出该日期。

let ref = Database.database().reference(withPath: "users").child("profile").child(uid).child("todos").child(String(self.getDate(self.dayNum)))

(getDate 函数是我用来获取当前日期的数字。例如 2 月 18 日将是“18”)

添加和存储任务完全正常。任务始终存储在正确的用户配置文件、待办事项列表路径和日期下。

问题

当用户将任务添加到数据库中没有存储先前任务的一天时,就会出现问题。

当您在不同日期之间切换时,例如从“26”到“27”,如果数据库中存储了以前的任务,那么它将正常加载每天的任务并相应地更新表。

但只有当这些日子有以前的任务已经存储在 Firebase RTD 中时,才会出现这种情况。

如果您在 Firebase 中没有存储某天的任务,UiTableView 只会显示您选择的前一天存储的任务,因为它在 RTD 中找不到路径。

例如,如果您点击“27”,并且它存储了当天的两个任务,然后移动到没有存储当天任务的“28”天,它将显示第 27 天的任务第 28 天。

我理解这是因为在加载任务时引用无法在 Firebase RTD 中找到路径,因为没有要加载的任务,因此路径不存在。

我试图在我的代码旁边发表评论以解释正在发生的一切

func loadTodos(n: Int)
        self.todos.removeAll() //removes all tasks from the array "todos"
        guard let uid = Auth.auth().currentUser?.uid else  return   //gets current user uid
         let ref = Database.database().reference(withPath: "users").child("profile").child(uid).child("todos").child(String(getDate(n)) //creates path to Firebase for specific day

 ref.observeSingleEvent(of: .value)  (snapshot) in
            for child in snapshot.children.allObjects as! [DataSnapshot]
                let todoName = child.key
                let todoRef = ref.child(todoName)
                
                todoRef.observeSingleEvent(of: .value)  (todoSnapshot) in
                    let value = todoSnapshot.value as? NSDictionary
                    let isChecked = value!["isChecked"] as? Bool
                    
                    self.todos.append(Todo(isChecked: isChecked!, todoName: todoName)) //adds new todo to array "todos"
                    self.todoTV.reloadData() //reloads UITableView "todoTV"
                
            //end of for
        //end of .observeSingleEvent
    //end of func

问题

我正在寻找是否有一种方法可以检测到路径不存在,并显示某种类型的消息而不是错误的日期任务。

我认为它可以像 if/else 语句一样简单地检测路径是否存在,如果不存在则显示消息。我只是不知道该怎么做。

我真的愿意接受任何其他解决方案。

我的目标是理想情况下我希望在没有任务的日子下放置一条消息,例如“添加任务”,一旦添加任务就会消失。

【问题讨论】:

我相信 firebase 有一个 .exists() 函数。我认为您可以调用诸如“Database.database().....child("todos").exists()”之类的东西,它将返回true或false..然后处理结果 【参考方案1】:

发生了什么

您只是在 for 循环中重新加载您的 tableView。

这意味着如果 for 循环有零个项目,您的表永远不会重新加载。

如何解决

这是您当前正在重新加载您的 tableView 的位置。

todoRef.observeSingleEvent(of: .value)  (todoSnapshot) in
                    let value = todoSnapshot.value as? NSDictionary
                    let isChecked = value!["isChecked"] as? Bool
                    
                    self.todos.append(Todo(isChecked: isChecked!, todoName: todoName)) //adds new todo to array "todos"
                    self.todoTV.reloadData() //reloads UITableView "todoTV"
                

而不是仅在第二个回调中使用它。也将其添加到第一个。像这样:

func loadTodos(n: Int)
        self.todos.removeAll() //removes all tasks from the array "todos"
        guard let uid = Auth.auth().currentUser?.uid else  return   //gets current user uid
         let ref = Database.database().reference(withPath: "users").child("profile").child(uid).child("todos").child(String(getDate(n)) //creates path to Firebase for specific day

 ref.observeSingleEvent(of: .value)  (snapshot) in
            for child in snapshot.children.allObjects as! [DataSnapshot]
                let todoName = child.key
                let todoRef = ref.child(todoName)
                
                todoRef.observeSingleEvent(of: .value)  (todoSnapshot) in
                    let value = todoSnapshot.value as? NSDictionary
                    let isChecked = value!["isChecked"] as? Bool
                    
                    self.todos.append(Todo(isChecked: isChecked!, todoName: todoName)) //adds new todo to array "todos"
                    self.todoTV.reloadData() //reloads UITableView "todoTV"
                
            //end of for
// ----- ----- ----- ----- ----- ----- ----- -----
            self.todoTV.reloadData() // ---- Reload Data Here Too ----
// ----- ----- ----- ----- ----- ----- ----- -----
        //end of .observeSingleEvent
    //end of func

这样,如果循环没有项目,表格仍然会重新加载空数据。

【讨论】:

以上是关于如果无法从 Firebase 实时数据库中检索数据,则尝试在 UITableView 上显示消息的主要内容,如果未能解决你的问题,请参考以下文章

无法从unity3d中的firebase实时数据库中检索数据

无法从从 Firebase 实时数据库中检索数据以在以下代码行中使用它的方法中获取返回值 [重复]

如何从 Firebase 实时数据库中检索值?

如何从 Firebase 实时数据库中检索特定数据?

从firebase实时数据库IOS Swift中检索数据

聊天应用中的Firebase实时数据库无法按时检索邮件