喜欢使用 firebase crash 的反馈。快速点赞-移除点赞
Like feedback using firebase crash. Fast click like-remove like
我有一个像 instagram 这样的应用程序。它有反馈页面。
当用户喜欢某个 post 时,我会添加此赞和反馈(使用其自己的密钥 (.childByAutoId
)。
static func add(_ newLike: LikeItem) {
// add like id for user feedback implementation
var like = newLike
let likeRef = ref.child("/userslikes/" + newLike.userId + "/onposts/" + newLike.postId).childByAutoId()
like.key = likeRef.key
var updates: [String: Any?] = [
"/userslikes/" + like.userId + "/onposts/" + like.postId: like.toAnyObject(),
"/postslikes/" + like.postId + "/" + like.userId: like.toAnyObject()
]
if like.userId != like.postAddedByUserId { // dont add your own likes
var likeForFeedBack = like.toAnyObject()
likeForFeedBack["isViewed"] = false // when user will open feedback -> true
updates.updateValue(likeForFeedBack, forKey: "/feedback/" + like.postAddedByUserId + "/" + like.key)
}
ref.updateChildValues(updates)
}
没关系。而且我还有 remove
功能。它将喜欢节点,从这个喜欢中获得这个喜欢和feedbackId
。然后我进行多部分更新。
static func remove(with userId: String, _ post: PostItem) {
var updates: [String: Any?] = [
"/userslikes/" + userId + "/onposts/" + post.key: nil,
"/postslikes/" + post.key + "/" + userId: nil
]
// deleting from feedback node
getLikeFromUser(id: userId, postId: post.key) { like in
if like.userId != like.postAddedByUserId {
updates.updateValue(nil, forKey: "/feedback/" + like.postAddedByUserId + "/" + like.key)
}
ref.updateChildValues(updates)
}
}
static func getLikeFromUser(id: String, postId: String,
completion: @escaping (_ likeId: LikeItem) -> Void) {
let refToLike = ref.child("/userslikes/" + id + "/onposts/" + postId)
refToLike.observeSingleEvent(of: .value, with: { snapshot in
let like = LikeItem(snapshot: snapshot)
completion(like)
})
}
所以,当用户点击 "remove like" 时,我有一些延迟(此时正在获取类似实体以获取反馈 ID)。
还有问题:如果我在发送垃圾邮件 like-removeLike
按钮(喜欢 - 删除喜欢 - l - rl - l - rl 等),有时我的反馈节点正在复制(使用不同的键。它没有删除旧节点),有时它没有添加(在这种情况下,如果我以后尝试删除它,它会崩溃)。
如何解决?
我的愚见,首先这可以通过用户体验限制来解决。用户不应该向应用程序中的任何按钮发送垃圾邮件。必须是这些事件之间的延迟。即使你可以添加一些最大值。在用户决定之间切换...等一下,然后再次释放它(也许)。
正如您在评论中所说,等待用户完成写入操作是个好主意和良好的用户体验。这样你就可以消除糟糕的用户体验。
您可以使用 userinteractionenabled 属性 的 UIView。
When set to NO, touch, press, keyboard, and focus events
intended for the view are ignored and removed from the event queue.
When set to YES, events are delivered to the view normally. The
default value of this property is YES.
During an animation, user
interactions are temporarily disabled for all views involved in the
animation, regardless of the value in this property. You can disable
this behavior by specifying the
UIViewAnimationOptionAllowUserInteraction option when configuring the
animation.
当然还有很多选择,天空是UX场景的极限。
您还可以查看 Apple 的用户界面加载指南:
https://developer.apple.com/ios/human-interface-guidelines/interaction/loading/
Show content as soon as possible. Don’t make people wait for content
to load before seeing the screen they're expecting. Show the screen
immediately, and use placeholder text, graphics, or animations to
identify where content isn't available yet. Replace these placeholder
elements as the content loads. Whenever possible, preload upcoming
content in the background, such as while an animation is playing or
the user is navigating a level or menu.
指标可能是:
https://developer.apple.com/ios/human-interface-guidelines/ui-controls/progress-indicators/
If it’s helpful, provide useful information while waiting for a task
to complete. Include a label above an activity indicator to give extra
context. Avoid vague terms like loading or authenticating because they
don’t usually add any value.
另一种选择
正如您在下面的评论中所说,还有另一种选择可以保留 like/dislike,直到用户生活在 ViewController。但是还有另一个 UX 问题,当用户尝试关闭模式或返回到以前的视图控制器时,他们将等待此后台作业完成。另一个问题是,如果用户终止了应用程序,您还剩下 1 个更改来保存数据,它是 AppDelegate 的 applicationWillTerminate。但是在那里保存数据是不好的做法,因为 5 秒限制:
This method lets your app know that it is about to be terminated and
purged from memory entirely. You should use this method to perform any
final clean-up tasks for your app, such as freeing shared resources,
saving user data, and invalidating timers. Your implementation of this
method has approximately five seconds to perform any tasks and return.
If the method does not return before time expires, the system may kill
the process altogether. For apps that do not support background
execution or are linked against iOS 3.x or earlier, this method is
always called when the user quits the app. For apps that support
background execution, this method is generally not called when the
user quits the app because the app simply moves to the background in
that case. However, this method may be called in situations where the
app is running in the background (not suspended) and the system needs
to terminate it for some reason. After calling this method, the app
also posts a UIApplicationWillTerminate notification to give
interested objects a chance to respond to the transition.
希望对您有所帮助。
我有一个像 instagram 这样的应用程序。它有反馈页面。
当用户喜欢某个 post 时,我会添加此赞和反馈(使用其自己的密钥 (.childByAutoId
)。
static func add(_ newLike: LikeItem) {
// add like id for user feedback implementation
var like = newLike
let likeRef = ref.child("/userslikes/" + newLike.userId + "/onposts/" + newLike.postId).childByAutoId()
like.key = likeRef.key
var updates: [String: Any?] = [
"/userslikes/" + like.userId + "/onposts/" + like.postId: like.toAnyObject(),
"/postslikes/" + like.postId + "/" + like.userId: like.toAnyObject()
]
if like.userId != like.postAddedByUserId { // dont add your own likes
var likeForFeedBack = like.toAnyObject()
likeForFeedBack["isViewed"] = false // when user will open feedback -> true
updates.updateValue(likeForFeedBack, forKey: "/feedback/" + like.postAddedByUserId + "/" + like.key)
}
ref.updateChildValues(updates)
}
没关系。而且我还有 remove
功能。它将喜欢节点,从这个喜欢中获得这个喜欢和feedbackId
。然后我进行多部分更新。
static func remove(with userId: String, _ post: PostItem) {
var updates: [String: Any?] = [
"/userslikes/" + userId + "/onposts/" + post.key: nil,
"/postslikes/" + post.key + "/" + userId: nil
]
// deleting from feedback node
getLikeFromUser(id: userId, postId: post.key) { like in
if like.userId != like.postAddedByUserId {
updates.updateValue(nil, forKey: "/feedback/" + like.postAddedByUserId + "/" + like.key)
}
ref.updateChildValues(updates)
}
}
static func getLikeFromUser(id: String, postId: String,
completion: @escaping (_ likeId: LikeItem) -> Void) {
let refToLike = ref.child("/userslikes/" + id + "/onposts/" + postId)
refToLike.observeSingleEvent(of: .value, with: { snapshot in
let like = LikeItem(snapshot: snapshot)
completion(like)
})
}
所以,当用户点击 "remove like" 时,我有一些延迟(此时正在获取类似实体以获取反馈 ID)。
还有问题:如果我在发送垃圾邮件 like-removeLike
按钮(喜欢 - 删除喜欢 - l - rl - l - rl 等),有时我的反馈节点正在复制(使用不同的键。它没有删除旧节点),有时它没有添加(在这种情况下,如果我以后尝试删除它,它会崩溃)。
如何解决?
我的愚见,首先这可以通过用户体验限制来解决。用户不应该向应用程序中的任何按钮发送垃圾邮件。必须是这些事件之间的延迟。即使你可以添加一些最大值。在用户决定之间切换...等一下,然后再次释放它(也许)。
正如您在评论中所说,等待用户完成写入操作是个好主意和良好的用户体验。这样你就可以消除糟糕的用户体验。
您可以使用 userinteractionenabled 属性 的 UIView。
When set to NO, touch, press, keyboard, and focus events intended for the view are ignored and removed from the event queue. When set to YES, events are delivered to the view normally. The default value of this property is YES.
During an animation, user interactions are temporarily disabled for all views involved in the animation, regardless of the value in this property. You can disable this behavior by specifying the UIViewAnimationOptionAllowUserInteraction option when configuring the animation.
当然还有很多选择,天空是UX场景的极限。
您还可以查看 Apple 的用户界面加载指南:
https://developer.apple.com/ios/human-interface-guidelines/interaction/loading/
Show content as soon as possible. Don’t make people wait for content to load before seeing the screen they're expecting. Show the screen immediately, and use placeholder text, graphics, or animations to identify where content isn't available yet. Replace these placeholder elements as the content loads. Whenever possible, preload upcoming content in the background, such as while an animation is playing or the user is navigating a level or menu.
指标可能是:
https://developer.apple.com/ios/human-interface-guidelines/ui-controls/progress-indicators/
If it’s helpful, provide useful information while waiting for a task to complete. Include a label above an activity indicator to give extra context. Avoid vague terms like loading or authenticating because they don’t usually add any value.
另一种选择
正如您在下面的评论中所说,还有另一种选择可以保留 like/dislike,直到用户生活在 ViewController。但是还有另一个 UX 问题,当用户尝试关闭模式或返回到以前的视图控制器时,他们将等待此后台作业完成。另一个问题是,如果用户终止了应用程序,您还剩下 1 个更改来保存数据,它是 AppDelegate 的 applicationWillTerminate。但是在那里保存数据是不好的做法,因为 5 秒限制:
This method lets your app know that it is about to be terminated and purged from memory entirely. You should use this method to perform any final clean-up tasks for your app, such as freeing shared resources, saving user data, and invalidating timers. Your implementation of this method has approximately five seconds to perform any tasks and return.
If the method does not return before time expires, the system may kill the process altogether. For apps that do not support background execution or are linked against iOS 3.x or earlier, this method is always called when the user quits the app. For apps that support background execution, this method is generally not called when the user quits the app because the app simply moves to the background in that case. However, this method may be called in situations where the app is running in the background (not suspended) and the system needs to terminate it for some reason. After calling this method, the app also posts a UIApplicationWillTerminate notification to give interested objects a chance to respond to the transition.
希望对您有所帮助。