I have installed Firebase for my Swift IOS App
In my AppDelegate file I import Firebase like this:
import Firebase
import FirebaseDatabase
and initialise it:
FirebaseApp.configure()
After that I check if database is connected and it prints out first "Not connected", but then "Connected", so I assume it is successful
var ref:DatabaseReference!
var databaseHandle:DatabaseHandle!
override func viewDidLoad() {
let connectedRef = Database.database().reference(withPath: ".info/connected")
connectedRef.observe(.value, with: { snapshot in
if snapshot.value as? Bool ?? false {
print("Connected")
} else {
print("Not connected")
}
})
}
But then I try to access my data and it gives me nothing!
ref = Database.database().reference()
databaseHandle = ref.child("Meal").observe(.childAdded, with: { (snapshot) in
print(snapshot.value as Any)
Here is snapshot from console Firebase
Also i can switch to realtime database, where is no data, but there i can allow reading/writing access (I set both to true)
"rules": {
".read": true,
".write": true
}
What could be the problem, so I can't get my data printed out?....
The problem is that you are trying to access Firestore with Firebase methods.
"But then I try to access my data and it gives me nothing!" It gives you nothing because there is no data in Firebase, all your data is in Firestore.
See this guide for Firestore: https://firebase.google.com/docs/firestore/quickstart
and this one to understand the differences between Firebase and Firestore:
https://firebase.google.com/docs/database/rtdb-vs-firestore
There is a difference in accessing Firebase Realtime Database and firestore data
You can access your cloud firestore data as shown below
In ViewDidLoad
let db = Firestore.firestore()
let ref = db.collection("Meal").document("\(myRiderUID!)")
db.collection("Meal").getDocuments() { (querySnapshot, err) in
if let err = err {
print("Error getting documents: \(err)")
} else {
for document in querySnapshot!.documents {
print("\(document.documentID) => \(document.data())")
}
}
}
Related
I want to load the required data in the AppDelagate so this is what I currently have in place:
// Override point for customization after application launch.
FirebaseApp.configure()
FirebaseFunctions().getCompanies()
DispatchGroup().wait()
return true
}
The function FirebaseFunctions().getCompanies() looks like the following:
func getCompanies(){
DispatchGroup().enter()
let db = Firestore.firestore()
db.collection("companies").getDocuments() { (querySnapshot, err) in
if let err = err {
print("Error getting documents: \(err)")
} else {
for document in querySnapshot!.documents {
let company = Company(name: document.documentID, discount: document.data()["discount"] as! String, website: document.data()["website"] as! String, code: document.data()["code"] as! String, categories: document.data()["categories"] as! String)
LocalData.companies.companyList.append(company)
}
}
DispatchGroup().leave()
}
}
However, when I use these functions and attempt to access my LocalData Class where the data is being stored, I am met with an error because they are loaded asynchronously. How can I delay the app in the AppDelagate until the data is loaded so that my UI can have access to the data?
I've used the sample code provided by the Firebase Documentation and it prints out the error message. I have no clue if the issue is within the code or within the structure of the database, as there are also sub-collections. In this case, I am trying to retrieve the "Home Title" field, however I heard that that's not possible (I may be wrong), so I'm trying to retrieve the "Sample Wedding" document, to no avail. This is my very first time programming a project in Swift and also using Firestore.
Here's my code:
let db = Firestore.firestore()
let docRef = db.collection("Weddings").document("Sample Wedding")
docRef.getDocument { (document, error) in
if let document = document, document.exists {
let dataDescription = document.data().map(String.init(describing:)) ?? "nil"
print("Document data: \(dataDescription)")
} else {
print("Document does not exist")
}
Here's my database structure:
]
You can try it like this
let db = Firestore.firestore()
db.collection("Weddings").document("Sample Wedding").getDocument {
(documentSnapshot, err) in
if let err = err {
print("Error getting documents: \(err)")
} else {
print("Document data: \(documentSnapshot)")
if let title = documentSnapshot.get("Home Title") as? String {
print(title)
}
}
}
I am using Firebase as my backend service & fetching data using the SnapshotListener ( which keep listening for any data changes ). I want to remove that listener (only run and fetch data on first load).
private func loadShops(_ category: String) {
db.collection(category).addSnapshotListener { snapshot, error in
guard error == nil else {
print(error!.localizedDescription)
return
}
if let docs = snapshot?.documents {
for doc in docs {
self.shops = []
let shopData = doc.data()
var newShop = Shop()
newShop.shopName = shopData["name"] as? String ?? "Empty Name"
self.shops.append(newShop)
self.shops.shuffle()
}
self.shopsView.tableView.reloadData()
}
}
}
Based on the API example above - I'm assuming you are using the Firestore API and not the older Firebase.
If its firestore, you could just use query fetch instead of using a snapshot listener.
Refer to https://firebase.google.com/docs/firestore/query-data/queries#execute_a_query
private func loadShops(_ category: String) {
db.collection(category).getDocuments() { (querySnapshot, err) in
if let err = err {
print("Error getting documents: \(err)")
} else if let querySnapshot = querySnapshot {
for document in querySnapshot.documents {
print("\(document.documentID) => \(document.data())")
// do the conversion to model object.
}
}
}
Using the snapshot listener is only if you want to continue monitoring the cloud for new documents. It is also costly as per the pricing documentation.
I'm currently trying to develop an ios application using Firestore, and when querying the database, I'm getting no results, as neither the if/else block execute. I'm wondering what is going wrong here...
db.collection("users").whereField("uid", isEqualTo: uid).getDocuments() { (querySnapshot, error) in
if let error = error {
print("Error getting documents: \(error.localizedDescription)")
} else {
for document in querySnapshot!.documents {
weight = document.data()["weight"]! as? Double
}
}
}
Database file structure
Update: I make a call to the database in an earlier method, and this properly returns the user's first name (when I add the weight, it also returns the correct value). But any subsequent calls fail to return anything. Hopefully that info helps.
I have the same Firestore structure like you, and this works for me:
func test() {
var accessLevel: Double?
let db = Firestore.firestore()
db.collection("users").whereField("uid", isEqualTo: UserApi.shared.CURRENT_USER_UID!).getDocuments() { (querySnapshot, error) in
if let error = error {
print("Error getting documents: \(error.localizedDescription)")
} else {
for document in querySnapshot!.documents {
accessLevel = document.data()["accessLevel"]! as? Double
print(accessLevel!)
}
}
}
}
Current uid:
// Actual logged-in User
var CURRENT_USER_UID: String? {
if let currentUserUid = Auth.auth().currentUser?.uid {
return currentUserUid
}
return nil
}
Hope it helps.
I need to get the information of my database made with Cloud Firestore. What I want is getting the documents or the collections. My code is attached below. It is perfectly connected with the database, however when I run the app, getdocuments is empty. Could anyone give me a hand? Thanks a lot.
self.db.collection("Students").getDocuments() { (querySnapshot, err) in
if let err = err {
print("Error getting documents: \(err)")
} else {
for document in querySnapshot!.documents {
print("\(document.documentID) => \(document.data())")
}
}
}
var db: Firestore!
override func viewDidLoad() {
super.viewDidLoad()
// [START setup]
let settings = FirestoreSettings()
Firestore.firestore().settings = settings
// [END setup]
db = Firestore.firestore()
}
The code in the question works for me with the exact structure posted. The only thing that I can see currently is this
let settings = FirestoreSettings()
As a shot in the dark, how about about changing your Firestore initialization to the following
var db: Firestore!
override func viewDidLoad() {
super.viewDidLoad()
self.db = Firestore.firestore()
let settings = self.db.settings
settings.areTimestampsInSnapshotsEnabled = true
self.db.settings = settings
}
Don't put "/Students"
let db = Firestore.firestore()
db.collection("Students").getDocuments() { (querySnapshot, err) in
if let err = err {
print("Error getting documents: \(err)")
} else {
for document in querySnapshot!.documents {
print("\(document.documentID) => \(document.data())")
}
}
}