Trouble retrieving data from Firebase using .Value/.Child added in swift - ios

i am working on a project where I am pulling data from firebase (which is "queued"). Essentially data is being saved w/ a time stamp so when it's called, it can be ordered sequentially (first in, first out).
The problem I am facing is when I retrieve the data on my app. From my research, on Stack overflow as well as firebase docs, .Value gives a snapshot and continues to listen to data when new data is added. However when new data is added it will take a new snapshot of the entire set (hence "duplicating data" on my app's array).
To get around this I have tried to instead use .ChildAdded, which works well to add new data to my array when new data is added to the firebase database. However it isn't adding the full data set (data that is already existing in the database), which is what I need in addition to new data being added.
Suppose firebase nodes as such:
App_Queue:
Category1:
Timestamp1:
Uid: User_1_uid
Timestamp2:
Uid: User_2_uid
Swift code (2.3):
Case1:
self.databaseRef.child("App_Queue/\(Category1)").queryLimitedToLast(15).observeEventType(.Value, withBlock: { (snapshot) in
if let userDict = snapshot.value as? [String:AnyObject]{
for each in userDict{
let timeIdExtract = each.0 as! String
self.timeIdArray.append(timeIdExtract)
print(self.timeIdArray)
}
//this gives me full snapshot of time stamps & a userId
//but if timestamp3 and user_3_uid is added to firebase, the array is appended with a new snapshot thus, duplicating items.
Case2:
self.databaseRef.child("App_Queue/\(Category1)").queryLimitedToLast(15).observeEventType(FIRDataEventType.ChildAdded, withBlock: { (snapshot : FIRDataSnapshot) in
if let userDict = snapshot.value as? [String:AnyObject]{
for each in userDict{
let timeIdExtract = each.0 as! String // Every follwers ID.
self.timeIdArray.append(timeIdExtract)
print(self.timeIdArray)
}
//this gives me only new items added, but not already added.
// if timestamp3 and user_3_uid is added the array is appended with this new item. But timestamp1 & timestamp2 not added
Case 3:
I have tried a hybrid of Case1 (instead use .observeSingleEventOfType()) & Case2, by adding a self.databaseRef.removeAllObservers() after the code in case 1, and then turning on the .ChildAdded observer for case2. It almost works.... added initial snapshot via case 1, then listens however if say, timestamp2 is recently added it will append this again when Case2 is called, thus duplicating the array.
So my question: how the heck do I go about getting existing objects in the database AND adding on new ones, without duplicating data in the array?
EDIT
Im silly-- had some extraneous code after the block which was throwing things off. DOH! For anyone experiencing issues, first place to check! also .ChildAdded paired with observeEventType did the trick. (takes all previous data already in DB + adds new data as it comes in).
self.databaseRef.child("App_Queue/\(Category1)").queryLimitedToLast(15).observeEventType(.ChildAdded, withBlock: { (snapshot) in
...

Im silly-- had some extraneous code after the block which was throwing things off. DOH! For anyone experiencing issues, first place to check! also .ChildAdded paired with observeEventType did the trick. (takes all previous data already in DB + adds new data as it comes in).
self.databaseRef.child("App_Queue/\(Category1)").queryLimitedToLast(15).observeEventType(.ChildAdded, withBlock: { (snapshot) in
...

Related

observeSingleEvent with queryEqual to value doesn't work

So, I want to check if user's device is in my list (for testing). For this I have a small set of values in my Firebase dataset.
It looks like that:
But when I'm trying to check if the user's id is in this list, I'm getting nothing.
let childString = "tempfreeuuid/"
let pointref = ref.child(childString)
let query = pointref.queryOrderedByKey().queryEqual(toValue: "FFFFF")
query.observeSingleEvent(of: DataEventType.value) { (snapshot) in
if snapshot.hasChildren() {
print("that's good")
} else {
print("snapshot has no children")
}
}
And the result is "snapshot has no children".
I've already tried query.observeSingleEvent(of: .childAdded) (doesn't work), .queryLimited(toFirst: 3), and .queryOrderedByKey() — these two don't work either.
At the same time this query is working if I'm not trying to use queryEqual.
What am I doing wrong?
update: I want to clarify the problem I have. I don't have any results, snapshot is null. At the same time if I'm using queryLimited(toFirst: 1) instead of queryEqual, I'm getting one result from the table to work with. It seems to me it's not about snapshot issues, it's about query without any results.
You are using the wrong OrderedBy method. Because you are using queryOrderedByKey the queryEqual function will check if its equal to the Key while you want to compare it to the Value.
Instead you should be using queryOrderedByChild or queryOrderedByValue to make sure you compare the right values.
Here is the reference to the firebase docs explaining how queries (specificly queryEqualToValue in your case) work.

iOS Firebase - Crash in simulator but not device w/ persistence

I tried googling this problem but it seems like everyone has the opposite problem where the app runs on simulator but not their device. I've been struggling a LOT all week with firebase asynchronous calls returning null and linked the issue to persistence being enabled. All my problems go away if I disable persistence, but I want it enabled. I learned recently about synchronous issues with the different listeners/persistence and have been struggling with firebase returning outdated/nil values for a while.
Simulator was working just a week or two ago and I'm not sure what's changed. I've tried messing with / switching out .observeSingleEvent for .observe and still crashes at this code:
let synced = ref.child("profiles").child((FIRAuth.auth()?.currentUser?.uid)!).child("level")
synced.observeSingleEvent(of: FIRDataEventType.value, with: { (snapshot) in
print(snapshot)
print(snapshot.ref)
if (snapshot.value as! String == "One") {
........//CRASH
With the message:
Could not cast value of type 'NSNull' (0x10b7cf8c8) to 'NSString' (0x10a9dfc40).
When I try to print snapshot, it shows me an empty snapshot. But when I print the ref, the link works and takes me to the right place in my db (where I can see the data exists)
Any ideas how to fix/get around this without disabling persistence? Or more importantly I guess, should I care that it doesn't work in simulator if it works on a device? Will this matter for app store approval / affect future users?
If you'd like to see for yourself that this is an issue of firebase getting a nil/outdated value when the reference exists, here is what I see when I follow the printed ref link
The error seems fairly explicit: there is no value, so you can't convert it to a string.
synced.observeSingleEvent(of: FIRDataEventType.value, with: { (snapshot) in
if (snapshot.exists()) {
if (snapshot.value as! String == "One") {
........//CRASH

Firebase - iOS suddenly returning null for snapshots that I know exist?

I came back to work on a project I have not touched in a week and suddenly my code was not working. I take a snapshot of data that I am sure exists (I can see it exactly in the database and changed no code) yet it is returning NSNULL for the snapshot and when I print snapshot.exists() I get false. I even tried printing snapshot.ref and typing that link into my browser and that takes me to the data on the console.
The only thing I did today was manually add a piece of data into my firebase console, but it was not in the same node where I am getting this error and it was working for a while after I made the change so I don't see how that could have caused this. Is anyone else having this issue or know why this would suddenly start happening?
Here is my code:
_ = ref.child("profiles").child((FIRAuth.auth()?.currentUser?.uid)!).child("type").observeSingleEventOfType(FIRDataEventType.Value, withBlock: { (snapshot) in
print(snapshot.exists())
print(snapshot.ref)
if (snapshot.value as! String == "Player") {
.....
}
})
I'm getting the error Could not cast value of type 'NSNull' (0x10d008600) to 'NSString' (0x10d3ffb48).' and as I said earlier snapshot.exists() is false and the ref link works.
Thanks!

Firebase: observeEventType() only returns one child

I'm trying to fetch the child from https://sizzling-heat-9137.firebaseio.com/users, which has 4. This is what I'm doing:
let ref = Firebase(url:"https://sizzling-heat-9137.firebaseio.com/users")
ref.observeEventType(.ChildAdded, withBlock: {
(snapshot) in
print("Snapshot: \(snapshot)")
})
According to the guides on Firebase this should give a snapshot of every child (4) and their data, but instead, I get the snapshot for only one child, call it X (the first one added but not first in order at /users).
When I do snapshot.childrenCountI get 7, which is the number of children in the first child X. Isn't that supposed to be four which is the total number of children at /users?
Am I doing something bad here or what could be the problem? I have tried both on the simulator and my real device.
I think you have to change your observeEventType from ChildAdded to FIRDataEventType.Value.
Then you can use your snapshot as dictionnary (for example) :
tempUser.firstName = snapshot.value!["firstname"] as! String
it will give number of children at the specified url. just check if ur url is pointing to that or the base of the nodes.

New Firebase - Cannot query data. What is the new syntax?

I am trying to move to the new Firebase from the old one (launched today, May 18th, 2016), but the query syntax is unclear to me. The only example I can find to make a query is via a listener.
I've followed the docs (https://firebase.google.com/docs/database/ios/retrieve-data), but they are very unclear as to how to simply query one piece of data in the Firebase realtime DB.
The old docs were fine, but the new ones are terrible, imo. Also, their examples on github, where I got some of the code I'm now trying to use, are overly complex (https://github.com/firebase/quickstart-ios/tree/master/database/DatabaseExampleSwift).
The code runs fine, I have a new project set up in the Firebase admin console online, I have the new plist file set up and in xcode, and everything compiles fine. I just need code to easily access one measly piece of data! Plz help.
Thanks.
Here's my code (runs fine / is configured fine), but can't display the data:
class LatestNewsTableViewController: UITableViewController {
// get the Feed URL from Firebase:
lazy var FireBaseRef: FIRDatabaseReference = FIRDatabase.database().reference()
var FeedURLRef: FIRDatabaseReference!
var refHandle: FIRDatabaseHandle?
Then, in viewDidLoad(), I'm doing this:
FeedURLRef = FireBaseRef.child("AppGlobals").child("FeedURL")
refHandle = FireBaseRef.observeEventType(FIRDataEventType.Value, withBlock: { (snapshot) in
let FirebaseFeedURL = snapshot.value as! [String : AnyObject]
print("FirebaseFeedURL = " + String(FirebaseFeedURL))
})

Resources