swift firestore check if documents exists - swift

using swift and firestore I want to check the "Taken User Names" collection to see if a username has been taken and if it has alert the user it taken otherwise if it's still available I want to create the file.
The gist of what I want to do is outlined below, I can save the data no problem though its the checking to see if its document exists then taking action that I cannot figure out
func nextButtonPressed(){
let db = Firestore.firestore()
if usernameTextField.text != ""{
guard let username = usernameTextField.text else { return }
let docRef = db.collection("Taken User Names").document(username)
// check if username exists{
//if exists alert user "sorry user name taken
} else {
// if user name doesn't exist
db.collection("Taken User Names").document("trinidad")
.setData(["Taken User Name" : (username)]) {
(error: Error?) in
if let error = error {
print("\(error.localizedDescription)")
} else {
print("document was succesfully created and written")
}
}
}
}

In a cleaner way:
let docRef = db.collection("collection").document("doc")
docRef.getDocument { (document, error) in
if document.exists {
print("Document data: \(document.data())")
} else {
print("Document does not exist")
}
}

func nextButtonPressed(){
let db = Firestore.firestore()
nextButton.isEnabled = false
if usernameTextField.text != ""{
guard let username = usernameTextField.text else { return }
guard let uid = Auth.auth().currentUser?.uid else { return }
let docRef = db.collection("Taken User Names").document(username)
docRef.getDocument { (document, error) in
if let document = document {
if document.exists{
print("Document data: \(document.data())")
self.alertTheUser(title: "Username Taken", message: "please choose again")
self.nextButton.isEnabled = true
} else {
print("Document does not exist")
}
}
}
}
}

try the following:
let db = Firestore.firestore()
guard let username = userNameTextField.text else { return }
let docRef = db.collection("users").whereField("username", isEqualTo: username).limit(to: 1)
docRef.getDocuments { (querysnapshot, error) in
if error != nil {
print("Document Error: ", error!)
} else {
if let doc = querysnapshot?.documents, !doc.isEmpty {
print("Document is present.")
}
}
}

Related

firestore fetch subcollection

I'm trying to fetch subcollection of my users document with code below
func readData(){
let userId = Auth.auth().currentUser?.uid
self.db.collection("users/\(userId)/saved").getDocuments { (snapshot, err) in
if let err = err {
print("err")
}
if let userId != nil {
for document in snapshot!.documents {
let docId = document.documentID
let cty = document.get("city") as! String
let ccode = document.get("code") as! String
let countr = document.get("country") as! String
print(cty, ccode, countr,docId)
}
}
}
but my code doesn't print anything, I don't understand the problem, documents exsist, see picture below
You're using illegal syntax with the userId check in the snapshot return but the logic flow is the bigger problem. I would recommend you check if the user is signed in before grabbing the subcollection and checking if there is a viable snapshot instead of checking the state of authentication.
func readData() {
guard let userId = Auth.auth().currentUser?.uid else {
return
}
db.collection("users/\(userId)/saved").getDocuments { (snapshot, error) in
guard let snapshot = snapshot else {
if let error = error {
print(error)
}
return
}
for doc in snapshot.documents {
guard let city = doc.get("city") as? String,
let code = doc.get("code") as? String,
let country = doc.get("country") as? String else {
continue // continue document loop
}
let docId = doc.documentID
print(city, code, country, docId)
}
}
}

IOS SWIFT5: check is specific field odcument exist in firestore

Seems there's no way to use boolean to return the checking result is exist or not. it only works in printing out the result...
func checkSeatAvailable() -> Bool{
var Exist: Bool
let g = DispatchGroup()
let resDate = ResDateTxt.text
let db = Firestore.firestore()
let docRef = db.collection("Reservations").whereField("resDate", isEqualTo: resDate!)
g.enter()
docRef.getDocuments() { (snapshot, error) in
if let snapshot = snapshot {
if snapshot.isEmpty {
print("Document does not exist")
Exist = true
g.leave()
} else {
print("Document data: \(snapshot) ")
Exist = false
g.leave()
}
}
}
g.notify(queue:.main) {}
print("\(Exist)")
return Exist
}
Add a completion Handler in your function as getDocuments function is asynchronous and return immediately. You can modify it like so.
func checkSeatAvailable(Completion:#escaping((Bool)->())){
//let g = DispatchGroup()
let resDate = ResDateTxt.text
let db = Firestore.firestore()
let docRef = db.collection("Reservations").whereField("resDate", isEqualTo: resDate!)
//g.enter()
docRef.getDocuments() { (snapshot, error) in
if let snapshot = snapshot {
if snapshot.isEmpty {
print("Document does not exist")
//g.leave()
} else {
print("Document data: \(snapshot) ")
Completion(true)
//g.leave()
}
}
}
//g.notify(queue:.main) {}
//print("\(Exist)")
//return Exist
}
And then call that function like that;
checkSeatAvailable { (boolValue) in
print(boolValue)
}

Struggling with basic Swift logic (Working with constants, variables and loops)

I want to use 2 Strings that I get with those two "loops" from firebase and use them in another "loop" to upload them with a bunch of other Information.
My problem is, that I somehow can't get the values of fullname and pfp that I downloaded, into the upload to firebase.
Any ideas on how to solve this issue?
func sendToFire(){
let combined = "\(userID)" + "\(number)"
let docRef = db.collection("posts").document(combined)
let description = self.textPost.text
let nameRef = db.collection("users").document(userID)
var fullname = ""
var pfp = ""
if fireImage == nil {
nameRef.getDocument { (document, error) in
if let document = document{
fullname = document.get("fullname") as! String
}else{
print("Coulnt get fullname")
}
}
nameRef.getDocument { (document, error) in
if let document = document{
pfp = document.get("profileimage") as! String
}else{
print("Couldn't get profileimage")
}
}
docRef.getDocument { (document, error) in
if let document = document, document.exists {
print("Post ID already taken")
} else {
print("Post Document gets created")
self.db.collection("posts").document(combined).setData([
"description": description!,
"likes": self.likes,
"postType": 0,
"profileImage": pfp,
"time": self.date,
"uid": self.userID,
"username": fullname
]) { err in
if let err = err {
print("Error writing document: \(err)")
} else {
print("Post Document successfully written!")
}
}
}
}
}
}
Add document.exists in the if let
nameRef.getDocument { (document, error) in
if let document = document, document.exists{
fullname = document.get("fullname") as! String
}else{
print("Coulnt get fullname")
}
}
nameRef.getDocument { (document, error) in
if let document = document, document.exists{
pfp = document.get("profileimage") as! String
}else{
print("Couldn't get profileimage")
}
}
Check the actual key names in the response fullname and profileimage.

Check and Add a document to the Firestore database (swift)

first I want to check if a doc with the Uid of the user is already created and if not, it should create a doc with the Uid of the user as a title.
Here is my code: (Somehow it doesnt work)
It gives me the error: Value of type 'CollectionReference' has no member 'doc'
#IBAction func GoogleSignIn(_ sender: Any) {
let db = Firestore.firestore()
guard let uid = Auth.auth().currentUser?.uid else { return }
let docRef = db.collection("users").document(uid)
let user: GIDGoogleUser = GIDSignIn.sharedInstance()!.currentUser
let fullName = user.profile.name
let email = user.profile.email
docRef.getDocument { (document, error) in
if let document = document {
if document.exists{
print("User already in Database")
} else {
print("User needs to get signed into Database")
db.collection("users").doc(uid).set([
"fullname" : fullName,
"email": email
])
}
GIDSignIn.sharedInstance()?.signIn()
}
is ".doc" a method? Don't you want db.collection("users").document(uid)

Check Firebase Storage before creating a new profile Image URL

I am having a bit of an issue checking Firebase Storage when a user logs into my app. When a user logs in an image is created and stored successfully in Firebase database and storage, but every time a user logs out and logs back into the app the profileImage file (not the child value url string) is duplicated in Firebase Storage as a new and separate image file.
I would like the app when logging in to check the Firebase storage for the profileImage file, and if it exists then do not re-create that same image in storage. I understand the logic of checking Firebase for image and if does not exist, than create new image. I am just having some trouble with the syntax. Thanks for help in advance!
// login user with Facebook
func loginWithFacebook() {
let accessToken = FBSDKAccessToken.current()
guard let accessTokenString = accessToken?.tokenString else { return }
let credentials = FIRFacebookAuthProvider.credential(withAccessToken: accessTokenString)
FIRAuth.auth()?.signIn(with: credentials, completion: { (user, error) in
if error != nil {
print("Something went wrong with our FB user: ", error ?? "")
return
}
guard let uid = user?.uid else {
return
}
let imageName = NSUUID().uuidString
let storageRef = FIRStorage.storage().reference().child("profile_images").child("\(imageName).png")
let photoUrl = user?.photoURL
// check to see if current user already has stored image with URL
if FIRStorage.storage().reference().child("profile_images").child("\(imageName).png") == nil {
if let imageData = NSData(contentsOf: photoUrl!) {
storageRef.put(imageData as Data, metadata:nil) {
(metadata, error) in
if error != nil {
print(error!)
return
} else {
if let profileImageUrl = metadata?.downloadURL()?.absoluteString {
let values = ["name": user!.displayName!, "email": user!.email!, "profileImageUrl": profileImageUrl]
self.registerUserWithUID(uid: uid, values: values as [String : AnyObject])
}
}
}
}
} else {
print("image already exists")
}
print("Successfully logged in with our user: ", user ?? "")
self.delegate?.finishLoggingIn()
})
private func registerUserWithUID(uid: String, values: [String: AnyObject]) {
// create items in database upon creating user ---------------
let ref = FIRDatabase.database().reference()
let usersReference = ref.child("users").child(uid)
usersReference.updateChildValues(values, withCompletionBlock: { (err, ref) in
if err != nil {
print(err!)
return
}
print("user has been saved to Firebase database")
})
}
I think the issue is with the "if" condition. You are referencing the location, but not checking with the actual data in that location.
You can implement that using .observerSingleEventOf().
private func checkUser (imageName:String, _ completionHandler: #escaping(Bool) -> Void)
{
let userExists = FIRStorage.storage().reference().child("profile_images")
userExists.observeSingleEvent(of: .value, with:{(snapshot) in
if snapshot.hasChild(imageName){
print ("Image already exists")
completionHandler(false)
}
else
{
print ("Image does not exist")
print ("store the image")
}
})
}
`