Swift 5 Firestore: Checking if collection exists in database - swift

I'm trying to check if a certain collection exists in my Firestore database, and here is my code for doing so:
let db = Firestore.firestore()
db.collection(pickedClass).getDocuments { (snapshot, error) in
if error == nil && snapshot != nil {
if snapshot!.documents.count > 0 {
for document in snapshot!.documents {
let documentData = document.data()
let info = documentData["info"] as! [String: Any]
output.append(object)
}
self.performSegue(withIdentifier: "showTutors", sender: output)
} else {
self.createAlert(title: "No Tutors Found", message: "Sorry, there are no tutors for this class", buttonMsg: "Okay")
}
}
}
The exception I get from running this apparently comes from the second line db.collection(pickedClass).getDocuments, and is as follows:
*** Terminating app due to uncaught exception 'FIRInvalidArgumentException', reason: 'Invalid collection reference. Collection references must have an odd number of segments, but has 0'
terminating with uncaught exception of type NSException
The bizarre thing is that most times this isn't an issue and the user sees the alert when the collection doesn't exist, but sometimes this happens. I never faced this issue until today, and I've been running this database and this snippet of code for over 2 months now.
Would really appreciate any help!

Hi, I'm implementing FireStore in first time as I study I found this
answer you can use this below mentioned code.
Firestore.firestore().collection("YOUR_COLLECTION_NAME_HERE")
.document("INSIDE_YOUR_COLLECTION_USE_DOCUMENT_ID_HERE_WHICH_YOU_WANT_TO_CHECK")
.getDocument { (document, error) in
debugPrint(document?.exists)
if document?.exists ?? false {
// EXIST
} else {
// NOT-EXIST
}
}

Related

Delete document from cloud firestore

I am trying to implement a function that allows the user to delete chats that they have with other users.
At the moment the code works and the firestore document is deleted successfully however as soon as the delete happens the code crashes and i get this error "Fatal error: Unexpectedly found nil while unwrapping an Optional value" next to the id = data!["id"] in the code. I guess that after the delete happens firestore keeps listening for documents and finds an empty collection following the delete. Does anyone know how to stop this from happening?
public func deleteConversation(conversationId: String, completion: #escaping (Bool) -> Void) {
// Get all conversations for current user
let CurrentUser = Auth.auth().currentUser?.uid
let db = Firestore.firestore()
let ConversationRef = db.collection("users").document(CurrentUser!).collection("conversations").document(test!)
print("deleting conversation with \(test!)")
ConversationRef.addSnapshotListener { snapshot, error in
guard let document = snapshot else {
print("Error getting documents: \(String(describing: error))")
return
}
let data = document.data()
if let id = data!["id"] as? String, id == conversationId {
print("conversation found")
ConversationRef.delete()
}
completion(true)
print("deleted conversation")
}
}
The problem comes from:
ConversationRef.addSnapshotListener { snapshot, error in
By calling addSnapshotListener you're adding a listener that:
Gets the document snapshot straight away,
Continues listening for changes and calls your code again then there are any.
The problem is in #2, as it means your code executes again when the document is deleted, and at that point document.data() will be nil.
The simplest fix is to only read the document once:
ConversationRef.getDocument { (document, error) in

swift 'Terminating app due to uncaught exception 'RLMException' Error

I am trying to add new data to realm
The following error occurs when trying to
realm.add(addData)
'Terminating app due to uncaught exception 'RLMException', reason: 'Attempting to create an object of type 'CalDBRealm' with an existing primary key value '2'.''
I tried with realm.create(CalDBRealm.self, value:addData, update: .modified) but no error
But this is not what I want. I want to add data, not update data.
What should I do?
Thank you
let realm = try! Realm()
let data = realm.objects(CalDBRealm.self).filter("date == %# AND listId == %#", todayDate, listId)
print("data type = \(data.count)")
if data.count > 0 {
time = data.first!.time
}
else
{
try! realm.write {
let addData = CalDBRealm("", todayDate, 0, "", listId)
//realm.add(addData)
realm.create(CalDBRealm.self, value:addData, update: .modified)
}
}

Firebase Firestore Query Using NSPredicate in Swift

According to the Firestore documentation, it is possible to create a Query using .filter(using: NSPredicate). I tried this using the following code (Swift 5, iOS 12.4, Xcode 11):
let predCondition = "title BEGINSWITH %#"
let searchKeyText = "Uxbridge"
let myPredicate = NSPredicate(format:predCondition, searchKeyText.lowercased())
let mapsRef = dbFS.collection("mapDetails")
let query = mapsRef.filter(using:myPredicate)
query.getDocuments()
{ (querySnapshot, err) in
if let snap = querySnapshot, snap.isEmpty
{
print("Document not found")
}
else
{
if let err = err
{
print("Error getting documents: \(err)")
}
else
{
for document in querySnapshot!.documents
{
print("\(document.documentID) => \(document.data())")
}
}
}
}
This compiled but resulted in an exception at run time:
*** Terminating app due to uncaught exception 'FIRInvalidArgumentException', reason: 'Invalid query. Operator type 8 is not supported.'
It seems that the type of predicate "title BEGINSWITH %#" is not supported. Does anyone know what types are available? I could not see anything in the documentation but if there is something I missed, I would appreciate it if someone would direct me to it. Also is there any possibility that BEGINSWITH, etc. may be supported in the near future? Thx. RB

Ignore records in FirebaseDB with swift

Im working on a swift app that displays records from firebase to a table view controller.
I have successfully been pulling in all data, But I have since added another field to the DB called "secretKey".. This doesn't not need to be used on the table view as its used elsewhere in the app
But now each time I try to run the app I get the following errors
2018-05-07 12:24:24.616490+0100 Loop Guardian[21847:9857567] *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<NSTaggedPointerString 0xa030818c015ea1f9> valueForUndefinedKey:]: this class is not key value coding-compliant for the key createdAt.'
*** First throw call stack:
(0x18204b164 0x181294528 0x18204ae2c 0x1829fe434 0x182944e20 0x182944874 0x18297d930 0x1030084b0 0x103008740 0x1030f2840 0x1044892cc 0x10448928c 0x10448dea0 0x181ff3344 0x181ff0f20 0x181f10c58 0x183dbcf84 0x18b6695c4 0x10301de44 0x181a3056c)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)
This only happens when the secretKey is present in the DB.. If I remove it the app works fine.
I somehow need to ignore this field
Heres the code used to pull the records from the DB
func observeMessages() {
let key = UserDefaults.standard.value(forKey: "uid") as! String
DBrefs.databaseMessages.child(key).observe(.value, with: { (snapshot) in
if snapshot.exists() {
let messageData = snapshot.value as! Dictionary<String, AnyObject>
self.dataArr = []
for (key,data) in messageData {
self.dataArr.append(data)
}
//THIS IS WHERE THE ERROR IS THROWN.. THREAD 1: SIGNAL SIGABRT
self.dataArr = (self.dataArr as NSArray).sortedArray(using: [NSSortDescriptor(key: "createdAt", ascending: true)]) as [AnyObject]
self.tblMessage.reloadData()
}
else {
}
})
}
Any help is appreciated
Thanks
Oliver
for (key,data) in messageData {
if (key == "secreyKey") {
continue;
}
self.dataArr.append(data)
}
Also use Swift method to sort the Array. Don't use NSArray use Array instead.
Like below code:
self.dataArr.sorted(by: {$0["createdAt"] as? Int64 ?? 0 < $1["createdAt"] as? Int64 ?? 0})

query if the data is found - Parse & Swift 3

I'm trying to develop an app that provide User sign up and within the UI I want to query if the email is exists or not.
The problem is since I change from swift 2 to swift 3 I got these errors
var query = PFObject(className:"User")
query.whereKey("email", equalTo: email)
query.findObjectsInBackground {
(objects, error) -> Void in
if error == nil {
// The find succeeded.
print("Successfully retrieved \(objects!.count) scores.")
// Do something with the found objects
if let objects = objects {
for object in objects {
print(object.objectId)
}
}
} else {
// Log details of the failure
print("Error: \(error!) \(error!.userInfo)")
}
}
/Users/**************/SignUpSenderViewController.swift:49:9:
Value of type 'PFObject' has no member 'whereKey'
/Users/i*************/SignUpSenderViewController.swift:50:9:
Value of type 'PFObject' has no member 'findObjectsInBackground'
any suggestion to solve this challenge ?
I dont know what documentation you checked but the query has to be done this way...
let query = PFQuery(className:"_User")