从 Firebase 检索 notificationTypes 的问题
Posted
技术标签:
【中文标题】从 Firebase 检索 notificationTypes 的问题【英文标题】:Issues retrieving notificationTypes from Firebase 【发布时间】:2020-02-04 22:49:47 【问题描述】:我有一个很长的问题,所以我提前道歉,我会尽力说明这一点。我正在尝试建立一个通知视图控制器,从 Firebase 调用不同类型的数据并设置不同的通知类型。
在上图中,这是用户向 Firebase 发送通知时单元格的外观。与调用并发布到屏幕上的特定通知类型相关联的用户。
在 firebase 结构中,我们看到存储的所有信息都保存在第一张图片中用户的 UID 下,并设置在该特定用户通知下,以显示谁在向他们发送正确的通知。这些用户名和图像与右侧的图像一样完美地显示出来。
我用来保存这些信息的代码如下,
fileprivate func saveSwipeToDataBase(didLike: Any)
let swipeDate = Int(NSDate().timeIntervalSince1970)
guard let uid = Auth.auth().currentUser?.uid else return
guard let cardUID = topCardView?.cardViewModel.uid else return
let documentData = ["workerId": uid,
"didLike": didLike,
"checked": 0,
"Swipe Date": swipeDate,
"type": SWIPE_INT_VALUE,
"posterId" : cardUID] as [String : Any]
self.postJobNotificationsIntoDatabseWithUID(uid: cardUID, values: documentData as [String : AnyObject])
private func postJobNotificationsIntoDatabseWithUID(uid: String, values: [String: AnyObject])
let ref = Database.database().reference(fromURL: "https://oddjobs-b131f.firebaseio.com/")
let usersReference = ref.child("notifications").child(uid).childByAutoId()
usersReference.setValue(values, withCompletionBlock: (err, ref) in
if err != nil
print("error saving data into firebase")
return
)
下面是我如何检索这些信息并将其存储到通知视图控制器中。
func fetchNotifications()
guard let currentUID = Auth.auth().currentUser?.uid else return
NOTIFICATIONS_REF.child(currentUID).observeSingleEvent(of: .value) (snapshot) in
guard let dictionary = snapshot.value as? Dictionary<String, AnyObject> else return
print(dictionary)
for (_, postingRawData) in dictionary
guard let postingDictionary = postingRawData as? Dictionary<String, AnyObject> else continue
guard let uid = postingDictionary["workerId"] as? String else continue
Database.fetchUser(with: uid, completion: (user) in
if let postId = postingDictionary["posterId"] as? String
Database.fetchPoster(with: postId, completion: (poster) in
let notification = userNotifications(user: user, poster: poster, dictionary: postingDictionary)
self.notifications.append(notification)
self.handleSortNotification()
)
else
let notification = userNotifications(user: user, dictionary: postingDictionary)
self.notifications.append(notification)
self.handleSortNotification()
)
现在我已经找到了正确的设置和展示方法,我将展示我的枚举以及我如何区分来自 firebase 的不同类型的调用。
class userNotifications
// MARK: - establish notificationTypes
enum NotificationType: Int, Printable
case swipe
case accepted
case confirmed
case completed
case pay
var description: String
switch self
case .swipe: return " swiped on your Job "
case .accepted: return " accepted you to complete the job, "
case .confirmed: return " confirmed the job"
case .completed: return " completed the job"
case .pay: return " pay for completed"
init(index: Int)
switch index
case 0: self = .swipe
case 1: self = .accepted
case 2: self = .confirmed
case 3: self = .completed
case 4: self = .pay
default: self = .swipe
// MARK: - access firebaseData
var creationDate: Date!
var timeDate: Date!
var uid: String!
var fromId: String?
var workerId: String?
var user: User!
var poster: Poster!
var type: Int?
var notificationType: NotificationType!
var didCheck = false
init(user: User? = nil, poster: Poster? = nil, dictionary: Dictionary<String, AnyObject>)
self.user = user
if let poster = poster
self.poster = poster
if let swipeDate = dictionary["Swipe Date"] as? Double
self.creationDate = Date(timeIntervalSince1970: swipeDate)
if let createDate = dictionary["creationDate"] as? Double
self.creationDate = Date(timeIntervalSince1970: createDate)
if let swipeDate = dictionary["time&date"] as? Double
self.timeDate = Date(timeIntervalSince1970: swipeDate)
if let type = dictionary["type"] as? Int
self.notificationType = NotificationType(index: type)
if let uid = dictionary["uid"] as? String
self.uid = uid
if let fromId = dictionary["fromId"] as? String
self.fromId = fromId
if let workerId = dictionary["workerUID"] as? String
self.workerId = workerId
if let checked = dictionary["checked"] as? Int
if checked == 0
self.didCheck = false
else
self.didCheck = true
以上是要设置的不同类型的通知。
现在,我的问题是,如果我调用不同的通知类型,例如 .accepted,则信息调用的方式非常不同。
上面的图片看起来是正确的,但是名称和图片不正确。它应该来自用户 ZacheryWilcox 而不是 Cjbwjdhbe。用户 Cjbwjdhbe 是当前用户,也是应该从 Zacherywilcox 接收通知的用户。不是来自自身。
在firebase中,信息保存为
我用来保存这些信息的代码如下
var workerUser: User?
didSet
let name = workerUser?.name
workerNameLabel.text = name
let workersUID = workerUser?.uid
workerNameLabel.text = name
guard let profileImage = workerUser?.profileImageUrl else return
workerImageView.loadImageUsingCacheWithUrlString(profileImage)
func saveUserData()
let workUser = self.workerUser
guard let uid = Auth.auth().currentUser?.uid else return
let workerId = workUser?.uid
Database.database().reference().child("users").child(uid).observeSingleEvent(of: .value, with: (snapshot) in
guard let dictionary = snapshot.value as? [String : Any] else return
let user = User(dictionary: dictionary as [String : AnyObject])
workUser?.uid = snapshot.key
self.datePicker.datePickerMode = UIDatePicker.Mode.date
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MMMM dd yyyy/ hh:mm a"
let selectedDate = dateFormatter.string(from: self.datePicker.date)
let creationDate = Int(NSDate().timeIntervalSince1970)
print(selectedDate)
let docData: [String: Any] = [
"workerId": workerId!,
"time&date": selectedDate,
"posterId" : uid,
"creationDate": creationDate,
"location": user.address!,
"type": 1,
"jobPost": "someUIDString",
"checked": 0,
]
self.postJobNotificationsIntoDatabseWithUID(uid: workerId!, values: docData as [String : AnyObject])
, withCancel: (err) in
print("attempting to load information")
)
print("Finished saving user info")
self.dismiss(animated: true, completion:
print("Dismissal complete")
)
private func postJobNotificationsIntoDatabseWithUID(uid: String, values: [String: AnyObject])
let ref = Database.database().reference(fromURL: "https://oddjobs-b131f.firebaseio.com/")
let usersReference = ref.child("notifications").child(uid).childByAutoId()
usersReference.setValue(values, withCompletionBlock: (err, ref) in
if err != nil
print("error saving data into firebase")
return
)
当使用 .accepted 类型来区分正在调用的通知类型时,发送通知的用户没有被正确设置,我不知道这背后的原因是什么。发送此信息的正确用户是 Zacherywilcox,用户的图像和名称应设置到用户的通知屏幕。不是用户 Cjbe... 我想知道是否有人可以帮助我解决这些问题。先感谢您。我开始认为我在接受用户时保存用户信息的方式不正确。
当我在 fetchingNotifications() 时,是否有可能自从调用
guard let uid = postingDictionary["workerId"] as? String else continue
Database.fetchUser(with: uid, completion: (user) in
if let postId = postingDictionary["posterId"] as? String
对发生的事情有影响吗?如果是这样,有没有办法区分正在调用的通知类型并获取各自用户调用的通知?
【问题讨论】:
只是对您的“通知”节点数据库结构的评论。看起来“fromid”总是与这些通知的用户 ID 键相同,因此您实际上不需要在每个通知上将其存储为“fromid”。每条通知记录将为您节省 28 个字节,您无需支付存储和数据传输费用。 【参考方案1】:只需将您的代码更新为:
func fetchNotifications()
guard let currentUID = Auth.auth().currentUser?.uid else return
NOTIFICATIONS_REF.child(currentUID).observeSingleEvent(of: .value) (snapshot) in
guard let dictionary = snapshot.value as? Dictionary<String, AnyObject> else return
print(dictionary)
let notificationId = snapshot.key
for (_, postingRawData) in dictionary
guard let postingDictionary = postingRawData as? Dictionary<String, AnyObject> else continue
guard let type = postingDictionary["type"] as? Int else continue
guard let uid = (type == userNotifications.NotificationType.accepted.rawValue) ? postingDictionary["fromId"] as? String : postingDictionary["workerId"] as? String else continue
Database.fetchUser(with: uid, completion: (user) in
if let postId = postingDictionary["fromId"] as? String
Database.fetchPoster(with: postId, completion: (poster) in
let notification = userNotifications(user: user, poster: poster, dictionary: postingDictionary)
self.notifications.append(notification)
self.handleSortNotification()
)
else
let notification = userNotifications(user: user, dictionary: postingDictionary)
self.notifications.append(notification)
self.handleSortNotification()
// NOTIFICATIONS_REF.child(currentUID).child(notificationId).child("checked").setValue(1)
)
这将解决您的问题。
【讨论】:
以上是关于从 Firebase 检索 notificationTypes 的问题的主要内容,如果未能解决你的问题,请参考以下文章