热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

iOS-Firebase观察单个事件调用两次

如何解决《iOS-Firebase观察单个事件调用两次》经验,应该怎么办?

我对Firebase和iOS开发相对较新,所以我希望有人能给我一些关于我做错的指导.出于某种原因,我的Observe中的代码块正在运行两次,即使ObserveSingleEvent特别应该在读取初始数据后终止观察.

我想要注意的是,这只发生在我的手机上(iPhone 7 iOS10).当我在模拟器中运行它时,我遇到了一个完全不同的问题,我得到了一个应该调用的调用,但是,当我的视图仍在上一个视图中时调用.本质上,应该在主屏幕加载其视图后调用此函数.但是,在模拟器中,当我在登录屏幕中对我的用户进行身份验证时,如果我没有用户名,则会创建弹出窗口,并且实际上不会将下一个视图显示到主屏幕.

这是引起问题的函数:

func initialSetUp() {
    print("initially set up")
    let userRef = FIRDatabase.database().reference(withPath: "/users/").child("\(uid!)")
    userRef.observeSingleEvent(of: .value, with: { (snapshot) in
        print("observing event")
        print("\(snapshot)")

        if snapshot.hasChild("username"){
           print("user has username")
        } else {
            print("user does not have username")
            //do stuff
            let nameRef = FIRDatabase.database().reference(withPath: "/usernames/")
            let alert = SCLAlertView()
            let appearance = SCLAlertView.SCLAppearance(
                kTitleFont: UIFont(name: "Futura-Medium", size: 20)!,
                kTextFont: UIFont(name: "Futura-Medium", size: 14)!,
                kButtonFont: UIFont(name: "Futura-Bold", size: 14)!,
                showCloseButton: false,
                shouldAutoDismiss: false
            )
            alert.appearance = appearance
            let newName = alert.addTextField("Enter your name")
            alert.addButton("Check name", backgroundColor: UIColor.black, textColor: UIColor.white, showDurationStatus: false) {
                UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to:nil, from:nil, for:nil)
                if let name = newName.text {
                    if name != "" {
                    //check if username is unique
                        nameRef.child(name.lowercased()).observeSingleEvent(of: FIRDataEventType.value, with: { (snapshot) in
                            print("\(snapshot.value)")
                            if !snapshot.exists() {
                                let alertView = SCLAlertView()
                                alertView.showSuccess("Woohoo!", subTitle: "This username is valid!")
                                print("valid username")
                            } else {
                                let alertView = SCLAlertView()
                                alertView.showError("Sorry :(", subTitle: "This username has already been taken.")
                            }
                        })
                    } else {
                        let alertView = SCLAlertView()
                        alertView.showError("Sorry :(", subTitle: "Your name can't be blank!")
                    }
                }

            }
            alert.addButton("Done", backgroundColor: UIColor.black, textColor: UIColor.white, showDurationStatus: false) {
                UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to:nil, from:nil, for:nil)
                if let name = newName.text {
                    if name != "" {
                        //check if username is unique
                        nameRef.child(name.lowercased()).observeSingleEvent(of: FIRDataEventType.value, with: { (snapshot) in
                            print("\(snapshot.value)")
                            if !snapshot.exists() {
                                alert.hideView()
                                let alertView = SCLAlertView()
                                alertView.showSuccess("Success!", subTitle: "You're all set to go!")
                                userRef.child("username").setValue(name)
                                nameRef.updateChildValues([name.lowercased(): self.uid])
                            } else {
                                let alertView = SCLAlertView()
                                alertView.showError("Sorry :(", subTitle: "This username has already been taken.")
                            }
                        })
                    } else {
                        let alertView = SCLAlertView()
                        alertView.showError("Sorry :(", subTitle: "Your name can't be blank!")
                    }
                }
            }
            alert.showCustom("Username", subTitle: "Please pick a user name!", color: UIColor.black, icon: SCLAlertViewStyleKit.imageOfEdit)
        }
    })
}

这是我的viewDidLoad

override func viewDidLoad() {
        self.view.addSubview(self.mapViewController.view)
        self.view.addSubview(self.tableController.view)
        print("View did load")          
        uid = (FIRAuth.auth()?.currentUser?.uid)!
        locatiOnsRef= FIRDatabase.database().reference(withPath: "/users/").child("\(uid)").child("locations")
        initialSetUp()
    }

我收到的输出看起来像这样

View did load
initially set up
observing event
user does not have username(or user does have username if I use a different account)
observing event
user does not have username(or user does have username if I use a different account)

我的Firebase数据结构:

截图

以下是打印快照时发生的情况

observing event
Snap (FJpA8PGCmwPRT9xjdrZENMIH8wJ3) {
    email = "test@gmail.com";
    id = 10207417529265514;
    name = "Jason";
}

如果需要,我很乐意提供更多信息,但我认为它可能是函数中的内容.


推荐阅读
  • 本文详细介绍了MySQL数据库的基础语法与核心操作,涵盖从基础概念到具体应用的多个方面。首先,文章从基础知识入手,逐步深入到创建和修改数据表的操作。接着,详细讲解了如何进行数据的插入、更新与删除。在查询部分,不仅介绍了DISTINCT和LIMIT的使用方法,还探讨了排序、过滤和通配符的应用。此外,文章还涵盖了计算字段以及多种函数的使用,包括文本处理、日期和时间处理及数值处理等。通过这些内容,读者可以全面掌握MySQL数据库的核心操作技巧。 ... [详细]
  • 开发技巧:在Interface Builder中实现UIButton文本居中对齐的方法与步骤
    开发技巧:在Interface Builder中实现UIButton文本居中对齐的方法与步骤 ... [详细]
  • Python 伦理黑客技术:深入探讨后门攻击(第三部分)
    在《Python 伦理黑客技术:深入探讨后门攻击(第三部分)》中,作者详细分析了后门攻击中的Socket问题。由于TCP协议基于流,难以确定消息批次的结束点,这给后门攻击的实现带来了挑战。为了解决这一问题,文章提出了一系列有效的技术方案,包括使用特定的分隔符和长度前缀,以确保数据包的准确传输和解析。这些方法不仅提高了攻击的隐蔽性和可靠性,还为安全研究人员提供了宝贵的参考。 ... [详细]
  • Android 自定义 RecycleView 左滑上下分层示例代码
    为了满足项目需求,需要在多个场景中实现左滑删除功能,并且后续可能在列表项中增加其他功能。虽然网络上有很多左滑删除的示例,但大多数封装不够完善。因此,我们尝试自己封装一个更加灵活和通用的解决方案。 ... [详细]
  • 如果应用程序经常播放密集、急促而又短暂的音效(如游戏音效)那么使用MediaPlayer显得有些不太适合了。因为MediaPlayer存在如下缺点:1)延时时间较长,且资源占用率高 ... [详细]
  • 本文介绍了在 Java 编程中遇到的一个常见错误:对象无法转换为 long 类型,并提供了详细的解决方案。 ... [详细]
  • 本文介绍如何在 Android 中自定义加载对话框 CustomProgressDialog,包括自定义 View 类和 XML 布局文件的详细步骤。 ... [详细]
  • oracle c3p0 dword 60,web_day10 dbcp c3p0 dbutils
    createdatabasemydbcharactersetutf8;alertdatabasemydbcharactersetutf8;1.自定义连接池为了不去经常创建连接和释放 ... [详细]
  • [转]doc,ppt,xls文件格式转PDF格式http:blog.csdn.netlee353086articledetails7920355确实好用。需要注意的是#import ... [详细]
  • MySQL 5.7 学习指南:SQLyog 中的主键、列属性和数据类型
    本文介绍了 MySQL 5.7 中主键(Primary Key)和自增(Auto-Increment)的概念,以及如何在 SQLyog 中设置这些属性。同时,还探讨了数据类型的分类和选择,以及列属性的设置方法。 ... [详细]
  • 实验九:使用SharedPreferences存储简单数据
    本实验旨在帮助学生理解和掌握使用SharedPreferences存储和读取简单数据的方法,包括程序参数和用户选项。 ... [详细]
  • 您的数据库配置是否安全?DBSAT工具助您一臂之力!
    本文探讨了Oracle提供的免费工具DBSAT,该工具能够有效协助用户检测和优化数据库配置的安全性。通过全面的分析和报告,DBSAT帮助用户识别潜在的安全漏洞,并提供针对性的改进建议,确保数据库系统的稳定性和安全性。 ... [详细]
  • 基于Net Core 3.0与Web API的前后端分离开发:Vue.js在前端的应用
    本文介绍了如何使用Net Core 3.0和Web API进行前后端分离开发,并重点探讨了Vue.js在前端的应用。后端采用MySQL数据库和EF Core框架进行数据操作,开发环境为Windows 10和Visual Studio 2019,MySQL服务器版本为8.0.16。文章详细描述了API项目的创建过程、启动步骤以及必要的插件安装,为开发者提供了一套完整的开发指南。 ... [详细]
  • 在《ChartData类详解》一文中,我们将深入探讨 MPAndroidChart 中的 ChartData 类。本文将详细介绍如何设置图表颜色(Setting Colors)以及如何格式化数据值(Formatting Data Values),通过 ValueFormatter 的使用来提升图表的可读性和美观度。此外,我们还将介绍一些高级配置选项,帮助开发者更好地定制和优化图表展示效果。 ... [详细]
  • MyISAM和InnoDB是MySQL中最为广泛使用的两种存储引擎,每种引擎都有其独特的优势和适用场景。MyISAM引擎以其简单的结构和高效的读取速度著称,适用于以读操作为主、对事务支持要求不高的应用。而InnoDB引擎则以其强大的事务处理能力和行级锁定机制,在需要高并发写操作和数据完整性的场景下表现出色。选择合适的存储引擎应综合考虑业务需求、性能要求和数据一致性等因素。 ... [详细]
author-avatar
amroc_394
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有