How do you make a function that has to do a query on the firebase database and return the value of the query...
We are currently making an iOS app and with firebase as its database. Please find below our code.
static func getTilesPerRow () -> Int{
let user = Auth.auth().currentUser
guard let uid = user?.uid else {
return -2
}
var ref: DatabaseReference!
ref = Database.database().reference()
let userRef = ref.child("user").child(uid)
var num = -1
let queue = DispatchQueue(label: "observer")
userRef.child("tilesPerRow").observe(DataEventType.value, with: { (snapshot) in
// Get user value
print("now inside the observe thing------------------")
let value = snapshot.value as? NSDictionary
num = snapshot.value as? Int ?? 0
print("just updated the number to ", num)
print("the snapshot is ", snapshot)
print("the value is ", value)
print("the real value is", snapshot.value)
print("just making sure, the number that was set is ", num)
}) { (error) in
print("there was an error!!!!!!!!!!!!!!!!!")
print(error.localizedDescription)
}
print("about to return from the function ", num)
return num
}
Currently while running this code, we get the following output.
about to return from the function -1
now inside the observe thing------------------
just updated the number to 5
the snapshot is Snap (tilesPerRow) 5
the value is nil
the real value is Optional(5)
just making sure, the number that was set is 5
Our expected output is:
now inside the observe thing------------------
just updated the number to 5
the snapshot is Snap (tilesPerRow) 5
the value is nil
the real value is Optional(5)
just making sure, the number that was set is 5
about to return from the function 5
The problem here is that we are trying to grab the value of what the query has found, but because .observe() is asynchronous, the function finishes before .observe() updates the value of num. How do we return the correct value?
ios swift firebase firebase-realtime-database
add a comment |
We are currently making an iOS app and with firebase as its database. Please find below our code.
static func getTilesPerRow () -> Int{
let user = Auth.auth().currentUser
guard let uid = user?.uid else {
return -2
}
var ref: DatabaseReference!
ref = Database.database().reference()
let userRef = ref.child("user").child(uid)
var num = -1
let queue = DispatchQueue(label: "observer")
userRef.child("tilesPerRow").observe(DataEventType.value, with: { (snapshot) in
// Get user value
print("now inside the observe thing------------------")
let value = snapshot.value as? NSDictionary
num = snapshot.value as? Int ?? 0
print("just updated the number to ", num)
print("the snapshot is ", snapshot)
print("the value is ", value)
print("the real value is", snapshot.value)
print("just making sure, the number that was set is ", num)
}) { (error) in
print("there was an error!!!!!!!!!!!!!!!!!")
print(error.localizedDescription)
}
print("about to return from the function ", num)
return num
}
Currently while running this code, we get the following output.
about to return from the function -1
now inside the observe thing------------------
just updated the number to 5
the snapshot is Snap (tilesPerRow) 5
the value is nil
the real value is Optional(5)
just making sure, the number that was set is 5
Our expected output is:
now inside the observe thing------------------
just updated the number to 5
the snapshot is Snap (tilesPerRow) 5
the value is nil
the real value is Optional(5)
just making sure, the number that was set is 5
about to return from the function 5
The problem here is that we are trying to grab the value of what the query has found, but because .observe() is asynchronous, the function finishes before .observe() updates the value of num. How do we return the correct value?
ios swift firebase firebase-realtime-database
2
I think it's a bad idea to try to make an asynchronous operation into a blocking synchronous function. That will make your app perform poorly. The APIs for mobile development are async for a reason: medium.com/google-developers/…
– Doug Stevenson
Nov 18 '18 at 2:05
2
The short answer is "You don't." You should make getTilesPerRow take a completion handler that gets called once the value is available.
– Duncan C
Nov 18 '18 at 2:46
add a comment |
We are currently making an iOS app and with firebase as its database. Please find below our code.
static func getTilesPerRow () -> Int{
let user = Auth.auth().currentUser
guard let uid = user?.uid else {
return -2
}
var ref: DatabaseReference!
ref = Database.database().reference()
let userRef = ref.child("user").child(uid)
var num = -1
let queue = DispatchQueue(label: "observer")
userRef.child("tilesPerRow").observe(DataEventType.value, with: { (snapshot) in
// Get user value
print("now inside the observe thing------------------")
let value = snapshot.value as? NSDictionary
num = snapshot.value as? Int ?? 0
print("just updated the number to ", num)
print("the snapshot is ", snapshot)
print("the value is ", value)
print("the real value is", snapshot.value)
print("just making sure, the number that was set is ", num)
}) { (error) in
print("there was an error!!!!!!!!!!!!!!!!!")
print(error.localizedDescription)
}
print("about to return from the function ", num)
return num
}
Currently while running this code, we get the following output.
about to return from the function -1
now inside the observe thing------------------
just updated the number to 5
the snapshot is Snap (tilesPerRow) 5
the value is nil
the real value is Optional(5)
just making sure, the number that was set is 5
Our expected output is:
now inside the observe thing------------------
just updated the number to 5
the snapshot is Snap (tilesPerRow) 5
the value is nil
the real value is Optional(5)
just making sure, the number that was set is 5
about to return from the function 5
The problem here is that we are trying to grab the value of what the query has found, but because .observe() is asynchronous, the function finishes before .observe() updates the value of num. How do we return the correct value?
ios swift firebase firebase-realtime-database
We are currently making an iOS app and with firebase as its database. Please find below our code.
static func getTilesPerRow () -> Int{
let user = Auth.auth().currentUser
guard let uid = user?.uid else {
return -2
}
var ref: DatabaseReference!
ref = Database.database().reference()
let userRef = ref.child("user").child(uid)
var num = -1
let queue = DispatchQueue(label: "observer")
userRef.child("tilesPerRow").observe(DataEventType.value, with: { (snapshot) in
// Get user value
print("now inside the observe thing------------------")
let value = snapshot.value as? NSDictionary
num = snapshot.value as? Int ?? 0
print("just updated the number to ", num)
print("the snapshot is ", snapshot)
print("the value is ", value)
print("the real value is", snapshot.value)
print("just making sure, the number that was set is ", num)
}) { (error) in
print("there was an error!!!!!!!!!!!!!!!!!")
print(error.localizedDescription)
}
print("about to return from the function ", num)
return num
}
Currently while running this code, we get the following output.
about to return from the function -1
now inside the observe thing------------------
just updated the number to 5
the snapshot is Snap (tilesPerRow) 5
the value is nil
the real value is Optional(5)
just making sure, the number that was set is 5
Our expected output is:
now inside the observe thing------------------
just updated the number to 5
the snapshot is Snap (tilesPerRow) 5
the value is nil
the real value is Optional(5)
just making sure, the number that was set is 5
about to return from the function 5
The problem here is that we are trying to grab the value of what the query has found, but because .observe() is asynchronous, the function finishes before .observe() updates the value of num. How do we return the correct value?
ios swift firebase firebase-realtime-database
ios swift firebase firebase-realtime-database
edited Nov 18 '18 at 4:57
Frank van Puffelen
231k28378402
231k28378402
asked Nov 18 '18 at 1:58
user9053278user9053278
11
11
2
I think it's a bad idea to try to make an asynchronous operation into a blocking synchronous function. That will make your app perform poorly. The APIs for mobile development are async for a reason: medium.com/google-developers/…
– Doug Stevenson
Nov 18 '18 at 2:05
2
The short answer is "You don't." You should make getTilesPerRow take a completion handler that gets called once the value is available.
– Duncan C
Nov 18 '18 at 2:46
add a comment |
2
I think it's a bad idea to try to make an asynchronous operation into a blocking synchronous function. That will make your app perform poorly. The APIs for mobile development are async for a reason: medium.com/google-developers/…
– Doug Stevenson
Nov 18 '18 at 2:05
2
The short answer is "You don't." You should make getTilesPerRow take a completion handler that gets called once the value is available.
– Duncan C
Nov 18 '18 at 2:46
2
2
I think it's a bad idea to try to make an asynchronous operation into a blocking synchronous function. That will make your app perform poorly. The APIs for mobile development are async for a reason: medium.com/google-developers/…
– Doug Stevenson
Nov 18 '18 at 2:05
I think it's a bad idea to try to make an asynchronous operation into a blocking synchronous function. That will make your app perform poorly. The APIs for mobile development are async for a reason: medium.com/google-developers/…
– Doug Stevenson
Nov 18 '18 at 2:05
2
2
The short answer is "You don't." You should make getTilesPerRow take a completion handler that gets called once the value is available.
– Duncan C
Nov 18 '18 at 2:46
The short answer is "You don't." You should make getTilesPerRow take a completion handler that gets called once the value is available.
– Duncan C
Nov 18 '18 at 2:46
add a comment |
1 Answer
1
active
oldest
votes
You don't.
To get the asynchronous operation result you use blocks.
static func getTilesPerRow (@escaping completion: (Int?)->Void ) {
let user = Auth.auth().currentUser
guard let uid = user?.uid else {
completion(nil)
}
var ref: DatabaseReference!
ref = Database.database().reference()
let userRef = ref.child("user").child(uid)
userRef.child("tilesPerRow").observeSingleEvent(DataEventType.value, with: { (snapshot) in
// Get user value
print("now inside the observe thing------------------")
let value = snapshot.value as? NSDictionary
let num = snapshot.value as? Int ?? 0
completion(num)
}) { (error) in
print("there was an error!!!!!!!!!!!!!!!!!")
print(error.localizedDescription)
completion(nil)
}
}
When the results are ready you will get notified through the block. Upon success you get the actual num
you are looking for or nil
upon any error occurred.
Even you can distinguish that what sort of error occurred by adding extra parameter on your parameter list in completion
block.
You also could use protocol, but thats require more knowledge like, in which class this code reside, who is the caller this sort of things. Set the protocol target to the caller, and upon completion called method will fire different protocol method based on the error or successful case occurred.
Happy coding.
1
What's the purpose of queue here? Firebase is asynchronous; UI calls within the closure are performed on the main thread and the closure will complete when the data is available from Firebase. Also, this code is using .value so it's kind of redundant; .value leaves an observer on the node in question so any time there's a change in the data the code within the closure would be called. It would probably be better to use .observeSingleEvent since it's being treated more as a function that returns a value. Other than that, good answer.
– Jay
Nov 18 '18 at 13:15
Thanks for pointing out the fixes.(+1)
– Ratul Sharker
Nov 18 '18 at 15:20
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53357251%2fhow-do-you-make-a-function-that-has-to-do-a-query-on-the-firebase-database-and-r%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
You don't.
To get the asynchronous operation result you use blocks.
static func getTilesPerRow (@escaping completion: (Int?)->Void ) {
let user = Auth.auth().currentUser
guard let uid = user?.uid else {
completion(nil)
}
var ref: DatabaseReference!
ref = Database.database().reference()
let userRef = ref.child("user").child(uid)
userRef.child("tilesPerRow").observeSingleEvent(DataEventType.value, with: { (snapshot) in
// Get user value
print("now inside the observe thing------------------")
let value = snapshot.value as? NSDictionary
let num = snapshot.value as? Int ?? 0
completion(num)
}) { (error) in
print("there was an error!!!!!!!!!!!!!!!!!")
print(error.localizedDescription)
completion(nil)
}
}
When the results are ready you will get notified through the block. Upon success you get the actual num
you are looking for or nil
upon any error occurred.
Even you can distinguish that what sort of error occurred by adding extra parameter on your parameter list in completion
block.
You also could use protocol, but thats require more knowledge like, in which class this code reside, who is the caller this sort of things. Set the protocol target to the caller, and upon completion called method will fire different protocol method based on the error or successful case occurred.
Happy coding.
1
What's the purpose of queue here? Firebase is asynchronous; UI calls within the closure are performed on the main thread and the closure will complete when the data is available from Firebase. Also, this code is using .value so it's kind of redundant; .value leaves an observer on the node in question so any time there's a change in the data the code within the closure would be called. It would probably be better to use .observeSingleEvent since it's being treated more as a function that returns a value. Other than that, good answer.
– Jay
Nov 18 '18 at 13:15
Thanks for pointing out the fixes.(+1)
– Ratul Sharker
Nov 18 '18 at 15:20
add a comment |
You don't.
To get the asynchronous operation result you use blocks.
static func getTilesPerRow (@escaping completion: (Int?)->Void ) {
let user = Auth.auth().currentUser
guard let uid = user?.uid else {
completion(nil)
}
var ref: DatabaseReference!
ref = Database.database().reference()
let userRef = ref.child("user").child(uid)
userRef.child("tilesPerRow").observeSingleEvent(DataEventType.value, with: { (snapshot) in
// Get user value
print("now inside the observe thing------------------")
let value = snapshot.value as? NSDictionary
let num = snapshot.value as? Int ?? 0
completion(num)
}) { (error) in
print("there was an error!!!!!!!!!!!!!!!!!")
print(error.localizedDescription)
completion(nil)
}
}
When the results are ready you will get notified through the block. Upon success you get the actual num
you are looking for or nil
upon any error occurred.
Even you can distinguish that what sort of error occurred by adding extra parameter on your parameter list in completion
block.
You also could use protocol, but thats require more knowledge like, in which class this code reside, who is the caller this sort of things. Set the protocol target to the caller, and upon completion called method will fire different protocol method based on the error or successful case occurred.
Happy coding.
1
What's the purpose of queue here? Firebase is asynchronous; UI calls within the closure are performed on the main thread and the closure will complete when the data is available from Firebase. Also, this code is using .value so it's kind of redundant; .value leaves an observer on the node in question so any time there's a change in the data the code within the closure would be called. It would probably be better to use .observeSingleEvent since it's being treated more as a function that returns a value. Other than that, good answer.
– Jay
Nov 18 '18 at 13:15
Thanks for pointing out the fixes.(+1)
– Ratul Sharker
Nov 18 '18 at 15:20
add a comment |
You don't.
To get the asynchronous operation result you use blocks.
static func getTilesPerRow (@escaping completion: (Int?)->Void ) {
let user = Auth.auth().currentUser
guard let uid = user?.uid else {
completion(nil)
}
var ref: DatabaseReference!
ref = Database.database().reference()
let userRef = ref.child("user").child(uid)
userRef.child("tilesPerRow").observeSingleEvent(DataEventType.value, with: { (snapshot) in
// Get user value
print("now inside the observe thing------------------")
let value = snapshot.value as? NSDictionary
let num = snapshot.value as? Int ?? 0
completion(num)
}) { (error) in
print("there was an error!!!!!!!!!!!!!!!!!")
print(error.localizedDescription)
completion(nil)
}
}
When the results are ready you will get notified through the block. Upon success you get the actual num
you are looking for or nil
upon any error occurred.
Even you can distinguish that what sort of error occurred by adding extra parameter on your parameter list in completion
block.
You also could use protocol, but thats require more knowledge like, in which class this code reside, who is the caller this sort of things. Set the protocol target to the caller, and upon completion called method will fire different protocol method based on the error or successful case occurred.
Happy coding.
You don't.
To get the asynchronous operation result you use blocks.
static func getTilesPerRow (@escaping completion: (Int?)->Void ) {
let user = Auth.auth().currentUser
guard let uid = user?.uid else {
completion(nil)
}
var ref: DatabaseReference!
ref = Database.database().reference()
let userRef = ref.child("user").child(uid)
userRef.child("tilesPerRow").observeSingleEvent(DataEventType.value, with: { (snapshot) in
// Get user value
print("now inside the observe thing------------------")
let value = snapshot.value as? NSDictionary
let num = snapshot.value as? Int ?? 0
completion(num)
}) { (error) in
print("there was an error!!!!!!!!!!!!!!!!!")
print(error.localizedDescription)
completion(nil)
}
}
When the results are ready you will get notified through the block. Upon success you get the actual num
you are looking for or nil
upon any error occurred.
Even you can distinguish that what sort of error occurred by adding extra parameter on your parameter list in completion
block.
You also could use protocol, but thats require more knowledge like, in which class this code reside, who is the caller this sort of things. Set the protocol target to the caller, and upon completion called method will fire different protocol method based on the error or successful case occurred.
Happy coding.
edited Nov 18 '18 at 15:18
answered Nov 18 '18 at 2:48
Ratul SharkerRatul Sharker
2,87711626
2,87711626
1
What's the purpose of queue here? Firebase is asynchronous; UI calls within the closure are performed on the main thread and the closure will complete when the data is available from Firebase. Also, this code is using .value so it's kind of redundant; .value leaves an observer on the node in question so any time there's a change in the data the code within the closure would be called. It would probably be better to use .observeSingleEvent since it's being treated more as a function that returns a value. Other than that, good answer.
– Jay
Nov 18 '18 at 13:15
Thanks for pointing out the fixes.(+1)
– Ratul Sharker
Nov 18 '18 at 15:20
add a comment |
1
What's the purpose of queue here? Firebase is asynchronous; UI calls within the closure are performed on the main thread and the closure will complete when the data is available from Firebase. Also, this code is using .value so it's kind of redundant; .value leaves an observer on the node in question so any time there's a change in the data the code within the closure would be called. It would probably be better to use .observeSingleEvent since it's being treated more as a function that returns a value. Other than that, good answer.
– Jay
Nov 18 '18 at 13:15
Thanks for pointing out the fixes.(+1)
– Ratul Sharker
Nov 18 '18 at 15:20
1
1
What's the purpose of queue here? Firebase is asynchronous; UI calls within the closure are performed on the main thread and the closure will complete when the data is available from Firebase. Also, this code is using .value so it's kind of redundant; .value leaves an observer on the node in question so any time there's a change in the data the code within the closure would be called. It would probably be better to use .observeSingleEvent since it's being treated more as a function that returns a value. Other than that, good answer.
– Jay
Nov 18 '18 at 13:15
What's the purpose of queue here? Firebase is asynchronous; UI calls within the closure are performed on the main thread and the closure will complete when the data is available from Firebase. Also, this code is using .value so it's kind of redundant; .value leaves an observer on the node in question so any time there's a change in the data the code within the closure would be called. It would probably be better to use .observeSingleEvent since it's being treated more as a function that returns a value. Other than that, good answer.
– Jay
Nov 18 '18 at 13:15
Thanks for pointing out the fixes.(+1)
– Ratul Sharker
Nov 18 '18 at 15:20
Thanks for pointing out the fixes.(+1)
– Ratul Sharker
Nov 18 '18 at 15:20
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53357251%2fhow-do-you-make-a-function-that-has-to-do-a-query-on-the-firebase-database-and-r%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
2
I think it's a bad idea to try to make an asynchronous operation into a blocking synchronous function. That will make your app perform poorly. The APIs for mobile development are async for a reason: medium.com/google-developers/…
– Doug Stevenson
Nov 18 '18 at 2:05
2
The short answer is "You don't." You should make getTilesPerRow take a completion handler that gets called once the value is available.
– Duncan C
Nov 18 '18 at 2:46