Swift/Decryption in search bar - ios

EDIT!!!
I got this search bar which with some data needs to decrypt it before searching. Im pretty sure I figured out where to decrypt it. But since im new, I cant really get it to work.
This is my function for filtered users. The data called "Personnr" needs to be decrypted before search.
I start by getting the String "ePersonnr" and the encryption key from the database. But when I run it, it just keeps adding a lot of profiles in the search bar?
func filterUsers (searchText:String) {
self.filteredUsers = self.usersArray.filter{ user in
var fNavn = false
var personNr = false
var searchBil = false
var telefonNr = false
var korekortNr = false
//This below is for the decryption
databaseRef.child("Buyers").queryOrdered(byChild: "ePersonnr").observe(.childAdded, with: { (snapshot) in
let key = snapshot.key
let snapshot = snapshot.value as? NSDictionary
snapshot?.setValue(key, forKey: "ePersonnr")
self.usersArray.append(snapshot)
self.ref = Database.database().reference()
self.ref.child("Encryption").child("key").observe(.value, with: { (snapshot) in
let uid = self.otherUser?["key"] as? String
self.otherUser = snapshot.value as? NSDictionary
self.otherUser?.setValue(uid, forKey: "key")
self.key1 = self.otherUser?["key1"] as? String
let input = key
let iv = self.key1
//Above is for the decryption
if let Navn = user!["Navn"] as? String {
fNavn = Navn.lowercased().contains(searchText.lowercased())
}
if let Bil = user!["Bil"] as? String {
searchBil = Bil.lowercased().contains(searchText.lowercased())
}
//Decryption of data
if let Personnr = user!["ePersonnr"] as? String {
let des = try! input.aesDecrypt(key: self.key1!, iv: iv!)
self.Personnr = des
personNr = Personnr.lowercased().contains(searchText.lowercased())
}
if let Kørekortnr = user!["Kørekortnr"] as? String {
korekortNr = Kørekortnr.lowercased().contains(searchText.lowercased())
}
if let Telefonnr = user!["Telefonnr"] as? String {
telefonNr = Telefonnr.lowercased().contains(searchText.lowercased())
}
}) { (error) in
print(error)
}
}) { (error) in
print(error)
}
return fNavn || personNr || searchBil || korekortNr || telefonNr
}
tableView.reloadData()
}
EDIT!!!
I checked in another project and the decryption works as it should. So its not the commands. It must be where to place the code. I guess.
This is how it looks like if I try to search:
https://ibb.co/cngfkb
Any ideas?

Related

Issues retrieving notificationTypes from Firebase

I have a bit of a lengthy question, So I apologize in advance I will try to illustrate this to the best of my abilities. I am trying to establish a notifications view controller that calls different types of data from Firebase and sets different notification types.
In the image above, this is how the cells should look when a user sends a notification to firebase. The user associated with that specific notification type as called and posted onto the screen.
In the firebase structure, We see that all of the information Stored is saved under the UID of the user in the first picture and is set under that specific users notification to show who is sending them a notification which is correct. These users names and images show perfectly as well as the image on the right.
The code I use to save this information is below,
fileprivate func saveSwipeToDataBase(didLike: Any) {
let swipeDate = Int(NSDate().timeIntervalSince1970)
guard let uid = Auth.auth().currentUser?.uid else { return }
guard let cardUID = topCardView?.cardViewModel.uid else { return }
let documentData = ["workerId": uid,
"didLike": didLike,
"checked": 0,
"Swipe Date": swipeDate,
"type": SWIPE_INT_VALUE,
"posterId" : cardUID] as [String : Any]
self.postJobNotificationsIntoDatabseWithUID(uid: cardUID, values: documentData as [String : AnyObject])
}
private func postJobNotificationsIntoDatabseWithUID(uid: String, values: [String: AnyObject]) {
let ref = Database.database().reference(fromURL: "https://oddjobs-b131f.firebaseio.com/")
let usersReference = ref.child("notifications").child(uid).childByAutoId()
usersReference.setValue(values, withCompletionBlock: { (err, ref) in
if err != nil {
print("error saving data into firebase")
return
}
})
}
And below is how I retrieve this information and store it onto the Notifications View controller.
func fetchNotifications() {
guard let currentUID = Auth.auth().currentUser?.uid else { return }
NOTIFICATIONS_REF.child(currentUID).observeSingleEvent(of: .value) { (snapshot) in
guard let dictionary = snapshot.value as? Dictionary<String, AnyObject> else { return }
print(dictionary)
for (_, postingRawData) in dictionary {
guard let postingDictionary = postingRawData as? Dictionary<String, AnyObject> else { continue }
guard let uid = postingDictionary["workerId"] as? String else { continue }
Database.fetchUser(with: uid, completion: { (user) in
if let postId = postingDictionary["posterId"] as? String {
Database.fetchPoster(with: postId, completion: {(poster) in
let notification = userNotifications(user: user, poster: poster, dictionary: postingDictionary)
self.notifications.append(notification)
self.handleSortNotification()
})
} else {
let notification = userNotifications(user: user, dictionary: postingDictionary)
self.notifications.append(notification)
self.handleSortNotification()
}
})
}
}
}
Now that I got the correct way to setup up and show out of the way, I will show my enum and how I am distinguishing the different types of calls from firebase.
class userNotifications {
// MARK: - establish notificationTypes
enum NotificationType: Int, Printable {
case swipe
case accepted
case confirmed
case completed
case pay
var description: String {
switch self {
case .swipe: return " swiped on your Job "
case .accepted: return " accepted you to complete the job, "
case .confirmed: return " confirmed the job"
case .completed: return " completed the job"
case .pay: return " pay for completed"
}
}
init(index: Int) {
switch index {
case 0: self = .swipe
case 1: self = .accepted
case 2: self = .confirmed
case 3: self = .completed
case 4: self = .pay
default: self = .swipe
}
}
}
// MARK: - access firebaseData
var creationDate: Date!
var timeDate: Date!
var uid: String!
var fromId: String?
var workerId: String?
var user: User!
var poster: Poster!
var type: Int?
var notificationType: NotificationType!
var didCheck = false
init(user: User? = nil, poster: Poster? = nil, dictionary: Dictionary<String, AnyObject>) {
self.user = user
if let poster = poster {
self.poster = poster
}
if let swipeDate = dictionary["Swipe Date"] as? Double {
self.creationDate = Date(timeIntervalSince1970: swipeDate)
}
if let createDate = dictionary["creationDate"] as? Double {
self.creationDate = Date(timeIntervalSince1970: createDate)
}
if let swipeDate = dictionary["time&date"] as? Double {
self.timeDate = Date(timeIntervalSince1970: swipeDate)
}
if let type = dictionary["type"] as? Int {
self.notificationType = NotificationType(index: type)
}
if let uid = dictionary["uid"] as? String {
self.uid = uid
}
if let fromId = dictionary["fromId"] as? String {
self.fromId = fromId
}
if let workerId = dictionary["workerUID"] as? String {
self.workerId = workerId
}
if let checked = dictionary["checked"] as? Int {
if checked == 0 {
self.didCheck = false
} else {
self.didCheck = true
}
}
}
}
Above is the different types of notifications to be set.
Now, My issue is If I call a different notification type, such as .accepted, the information calls in a very different way.
The image above seems correct, However, the name and image are incorrect. it should be from the user ZacheryWilcox instead of Cjbwjdhbe. the user Cjbwjdhbe is the current user and the user who should be receing a notification from Zacherywilcox. not from itself.
In firebase, the information is saved as
the code I use to save this information is below
var workerUser: User? {
didSet {
let name = workerUser?.name
workerNameLabel.text = name
let workersUID = workerUser?.uid
workerNameLabel.text = name
guard let profileImage = workerUser?.profileImageUrl else { return }
workerImageView.loadImageUsingCacheWithUrlString(profileImage)
}
}
func saveUserData() {
let workUser = self.workerUser
guard let uid = Auth.auth().currentUser?.uid else { return }
let workerId = workUser?.uid
Database.database().reference().child("users").child(uid).observeSingleEvent(of: .value, with: { (snapshot) in
guard let dictionary = snapshot.value as? [String : Any] else { return }
let user = User(dictionary: dictionary as [String : AnyObject])
workUser?.uid = snapshot.key
self.datePicker.datePickerMode = UIDatePicker.Mode.date
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MMMM dd yyyy/ hh:mm a"
let selectedDate = dateFormatter.string(from: self.datePicker.date)
let creationDate = Int(NSDate().timeIntervalSince1970)
print(selectedDate)
let docData: [String: Any] = [
"workerId": workerId!,
"time&date": selectedDate,
"posterId" : uid,
"creationDate": creationDate,
"location": user.address!,
"type": 1,
"jobPost": "someUIDString",
"checked": 0,
]
self.postJobNotificationsIntoDatabseWithUID(uid: workerId!, values: docData as [String : AnyObject])
}, withCancel: { (err) in
print("attempting to load information")
})
print("Finished saving user info")
self.dismiss(animated: true, completion: {
print("Dismissal complete")
})
}
private func postJobNotificationsIntoDatabseWithUID(uid: String, values: [String: AnyObject]) {
let ref = Database.database().reference(fromURL: "https://oddjobs-b131f.firebaseio.com/")
let usersReference = ref.child("notifications").child(uid).childByAutoId()
usersReference.setValue(values, withCompletionBlock: { (err, ref) in
if err != nil {
print("error saving data into firebase")
return
}
})
}
When the type .accepted is being used to differentiate what notificationType is being called, the user who sent the notification is not being set correctly and I have no idea what is the reasoning behind this. The correct user that is sending this information over is Zacherywilcox, and that users image and name should be set to the user's notification screen. not the user Cjbe... I was wondering if anyone could help me fix these issues. Thank you in advance. I'm starting to think that the way I am saving the users information when accepting the user is incorrect.
When I am fetchingNotifications(), is it possible that since calling
guard let uid = postingDictionary["workerId"] as? String else { continue }
Database.fetchUser(with: uid, completion: { (user) in
if let postId = postingDictionary["posterId"] as? String {
has an effect on whats going on? if so, Is there a way to differentiate between what notificationType is being called and fetch what notifications has been called with their respective users?
Just update your code to:
func fetchNotifications() {
guard let currentUID = Auth.auth().currentUser?.uid else { return }
NOTIFICATIONS_REF.child(currentUID).observeSingleEvent(of: .value) { (snapshot) in
guard let dictionary = snapshot.value as? Dictionary<String, AnyObject> else { return }
print(dictionary)
let notificationId = snapshot.key
for (_, postingRawData) in dictionary {
guard let postingDictionary = postingRawData as? Dictionary<String, AnyObject> else { continue }
guard let type = postingDictionary["type"] as? Int else { continue }
guard let uid = (type == userNotifications.NotificationType.accepted.rawValue) ? postingDictionary["fromId"] as? String : postingDictionary["workerId"] as? String else { continue }
Database.fetchUser(with: uid, completion: { (user) in
if let postId = postingDictionary["fromId"] as? String {
Database.fetchPoster(with: postId, completion: {(poster) in
let notification = userNotifications(user: user, poster: poster, dictionary: postingDictionary)
self.notifications.append(notification)
self.handleSortNotification()
})
} else {
let notification = userNotifications(user: user, dictionary: postingDictionary)
self.notifications.append(notification)
self.handleSortNotification()
}
// NOTIFICATIONS_REF.child(currentUID).child(notificationId).child("checked").setValue(1)
})
}
}
}
This will solve your problem.

AddSnapShotListener is repeating the document reading in one instance

When I am using addSnapshotListener for realtime updates, the documents are repeated which should not be the case, but when using getDocuments() the documents are repeated once only, I need to use addSnaphotListener but not want to duplicate the document reading, please assist where I am wrong in using snapshot listener.
I am using Firestore database in Swift iOS. Below is the code I am using
Code with addSnapShotListener():
func getComments() {
//print(postId + "received")
let commentsRef = Firestore.firestore().collection("posts").document(postId).collection("comments")
commentsRef.addSnapshotListener { (snapshot, error) in
if let error = error {
print(error.localizedDescription)
} else {
if let snapshot = snapshot {
for document in snapshot.documents {
// self.length = snapshot.count
let data = document.data()
let username = data["comment_author_username"] as? String ?? ""
let comment = data["comment_author_comment"] as? String ?? ""
let spinnerC = data["comment_author_spinnerC"] as? String ?? ""
let fullname = data["comment_author_fullname"] as? String ?? ""
let email = data["comment_author_email"] as? String ?? ""
let commentUserImageUrl = data["comment_user_image"] as? String ?? ""
let commentuser_id = data["comment_author_id"] as? String ?? ""
self.checkl1value = data["l1"] as? Bool
let newComment = Comment(_documentId: document.documentID, _commentAuthorUsername: username, _commentAuthorFullName: fullname, _commentAuthorComment: comment, _commentUserImage: commentUserImageUrl, _commentAuthorSpinnerC: spinnerC, _commentAuthorId:commentuser_id, _checkl1value: self.checkl1value)
self.comments.append(newComment)
// print(self.length!)
}
self.tableView.reloadData()
}
}
}
}
Code With getDocuments():
func getComments() {
//print(postId + "received")
let commentsRef = Firestore.firestore().collection("posts").document(postId).collection("comments")
commentsRef.getDocuments { (snapshot, error) in
if let error = error {
print(error.localizedDescription)
} else {
if let snapshot = snapshot {
for document in snapshot.documents {
// self.length = snapshot.count
let data = document.data()
let username = data["comment_author_username"] as? String ?? ""
let comment = data["comment_author_comment"] as? String ?? ""
let spinnerC = data["comment_author_spinnerC"] as? String ?? ""
let fullname = data["comment_author_fullname"] as? String ?? ""
let email = data["comment_author_email"] as? String ?? ""
let commentUserImageUrl = data["comment_user_image"] as? String ?? ""
let commentuser_id = data["comment_author_id"] as? String ?? ""
self.checkl1value = data["l1"] as? Bool
let newComment = Comment(_documentId: document.documentID, _commentAuthorUsername: username, _commentAuthorFullName: fullname, _commentAuthorComment: comment, _commentUserImage: commentUserImageUrl, _commentAuthorSpinnerC: spinnerC, _commentAuthorId:commentuser_id, _checkl1value: self.checkl1value)
self.comments.append(newComment)
// print(self.length!)
}
self.tableView.reloadData()
}
}
}
}
You're probably looking to only handle the changes between the snapshots. To do that you'll want to loop over instead of, as shown in the documentation on viewing changes between snapshots:
db.collection("cities").whereField("state", isEqualTo: "CA")
.addSnapshotListener { querySnapshot, error in
guard let snapshot = querySnapshot else {
print("Error fetching snapshots: \(error!)")
return
}
snapshot.documentChanges.forEach { diff in
if (diff.type == .added) {
print("New city: \(diff.document.data())")
}
if (diff.type == .modified) {
print("Modified city: \(diff.document.data())")
}
if (diff.type == .removed) {
print("Removed city: \(diff.document.data())")
}
}
}
Initially your listener will get called with diff.type == .added for each existing document, and then when there are changes it'll get called with the right mix of types.

Compiler crashes saying a variable from FIR database is unexpectedly nil, millisecs after reading the desired value

here's the function that I call that crashes:
func retrieveOtherUserData(){
profileRef.queryOrdered(byChild: "uid").queryEqual(toValue: "aRandomUserID6388").observe(.value, with:{
snapshot in
print("snapshot.value is \(snapshot.value!)")
for item in snapshot.children {
let profile = Profile(snapshot: item as! FIRDataSnapshot)
otherUID = profile!.userId!
otherUserName = profile!.firstName!
otherUserProfilePicURLString = profile!.fbDownloadURLForMediumProfPic!
}
})
}
It consistently says unexpectedly found nil when force unwrapping the profile statements. Here's what profile is referencing:
import Foundation
import UIKit
import Firebase
class Profile: NSObject {
var userId: String!
var firstName: String!
var age: Int!
var birthday: String!
var gender: String!
var education: String!
var thisIsMyFun: String!
var iAm: String!
var location: String!
var userLat: Double!
var userLong: Double!
var firStorageNameForFB1: String!
var firStorageNameForFB2: String!
var firStorageNameForFB3: String?
var firStorageNameForFB4: String?
var firStorageNameForFB5: String?
var firStorageNameForFB6: String?
var firStorageNameForFB7: String?
var firStorageNameForFB8: String?
var firStorageNameForFB9: String?
var firStorageNameForFB10: String?
var firStorageNameForPH1: String?
var firStorageNameForPH2: String?
var fbDownloadURLForSmallProfPic: String!
var fbDownloadURLForMediumProfPic: String!
var fbDownloadURLForLargeProfPic: String!
var firDownloadURLForFB1: String!
var firDownloadURLForFB2: String!
var firDownloadURLForFB3: String?
var firDownloadURLForFB4: String?
var firDownloadURLForFB5: String?
var firDownloadURLForFB6: String?
var firDownloadURLForFB7: String?
var firDownloadURLForFB8: String?
var firDownloadURLForFB9: String?
var firDownloadURLForFB10: String?
var firDownloadURLForPH1: String?
var firDownloadURLForPH2: String?
var profileKey: String!
var profileRef: FIRDatabaseReference!
init?(snapshot: FIRDataSnapshot) {
guard let dict = snapshot.value as? [String: Any] else { return nil }
guard let userId = dict["uid"] else { return nil }
guard let firstName = dict["name"] else { return nil }
guard let age = dict["age"] else { return nil }
guard let birthday = dict["birthday"] else { return nil }
guard let gender = dict["gender"] else { return nil }
guard let education = dict["education"] else { return nil }
guard let thisIsMyFun = dict["bodyOfThisIsMyFun"] else { return nil }
guard let iAm = dict["bodyOfIAM"] else { return nil }
guard let location = dict["locationOfUser"] else { return nil }
guard let userLat = dict["latitudeOfUser"] else { return nil }
guard let userLong = dict["longitudeOfUser"] else { return nil }
guard let firStorageNameForFB1 = dict["firStorageNameForFBPhoto1"] else { return nil }
guard let firStorageNameForFB2 = dict["firStorageNameForFBPhoto2"] else { return nil }
guard let firStorageNameForFB3 = dict["firStorageNameForFBPhoto3"] else { return nil }
guard let firStorageNameForFB4 = dict["firStorageNameForFBPhoto4"] else { return nil }
guard let firStorageNameForFB5 = dict["firStorageNameForFBPhoto5"] else { return nil }
guard let firStorageNameForFB6 = dict["firStorageNameForFBPhoto6"] else { return nil }
guard let firStorageNameForFB7 = dict["firStorageNameForFBPhoto7"] else { return nil }
guard let firStorageNameForFB8 = dict["firStorageNameForFBPhoto8"] else { return nil }
guard let firStorageNameForFB9 = dict["firStorageNameForFBPhoto9"] else { return nil }
guard let firStorageNameForFB10 = dict["firStorageNameForFBPhoto10"] else { return nil }
guard let firStorageNameForPH1 = dict["firStorageNameForPHPhoto1"] else { return nil }
guard let firStorageNameForPH2 = dict["firStorageNameForPHPhoto2"] else { return nil }
guard let fbDownloadURLForSmallProfPic = dict["URLofSmallFBProfPic"] else { return nil }
guard let fbDownloadURLForMediumProfPic = dict["URLofMediumFBProfPic"] else { return nil }
guard let fbDownloadURLForLargeProfPic = dict["URLofLargeFBProfPic"] else { return nil }
guard let firDownloadURLForFB1 = dict["firDownloadURLStringForFBPic1"] else { return nil }
guard let firDownloadURLForFB2 = dict["firDownloadURLStringForFBPic2"] else { return nil }
guard let firDownloadURLForFB3 = dict["firDownloadURLStringForFBPic3"] else { return nil }
guard let firDownloadURLForFB4 = dict["firDownloadURLStringForFBPic4"] else { return nil }
guard let firDownloadURLForFB5 = dict["firDownloadURLStringForFBPic5"] else { return nil }
guard let firDownloadURLForFB6 = dict["firDownloadURLStringForFBPic6"] else { return nil }
guard let firDownloadURLForFB7 = dict["firDownloadURLStringForFBPic7"] else { return nil }
guard let firDownloadURLForFB8 = dict["firDownloadURLStringForFBPic8"] else { return nil }
guard let firDownloadURLForFB9 = dict["firDownloadURLStringForFBPic9"] else { return nil }
guard let firDownloadURLForFB10 = dict["firDownloadURLStringForFBPic10"] else { return nil }
guard let firDownloadURLForPH1 = dict["firDownloadURLStringForPHPic1"] else { return nil }
guard let firDownloadURLForPH2 = dict["firDownloadURLStringForPHPic2"] else { return nil }
self.userId = userId as! String
self.firstName = firstName as! String
self.age = age as! Int
self.birthday = birthday as! String
self.gender = gender as! String
self.education = education as! String
self.thisIsMyFun = thisIsMyFun as! String
self.iAm = iAm as! String
self.location = location as! String
self.userLat = userLat as! Double
self.userLong = userLong as! Double
self.firStorageNameForFB1 = firStorageNameForFB1 as! String
self.firStorageNameForFB2 = firStorageNameForFB2 as! String
self.firStorageNameForFB3 = firStorageNameForFB3 as? String
self.firStorageNameForFB4 = firStorageNameForFB4 as? String
self.firStorageNameForFB5 = firStorageNameForFB5 as? String
self.firStorageNameForFB6 = firStorageNameForFB6 as? String
self.firStorageNameForFB7 = firStorageNameForFB7 as? String
self.firStorageNameForFB8 = firStorageNameForFB8 as? String
self.firStorageNameForFB9 = firStorageNameForFB9 as? String
self.firStorageNameForFB10 = firStorageNameForFB10 as? String
self.firStorageNameForPH1 = firStorageNameForPH1 as? String
self.firStorageNameForPH2 = firStorageNameForPH2 as? String
self.fbDownloadURLForSmallProfPic = fbDownloadURLForSmallProfPic as! String
self.fbDownloadURLForMediumProfPic = fbDownloadURLForMediumProfPic as! String
self.fbDownloadURLForLargeProfPic = fbDownloadURLForLargeProfPic as! String
self.firDownloadURLForFB1 = firDownloadURLForFB1 as! String
self.firDownloadURLForFB2 = firDownloadURLForFB2 as! String
self.firDownloadURLForFB3 = firDownloadURLForFB3 as? String
self.firDownloadURLForFB4 = firDownloadURLForFB4 as? String
self.firDownloadURLForFB5 = firDownloadURLForFB5 as? String
self.firDownloadURLForFB6 = firDownloadURLForFB6 as? String
self.firDownloadURLForFB7 = firDownloadURLForFB7 as? String
self.firDownloadURLForFB8 = firDownloadURLForFB8 as? String
self.firDownloadURLForFB9 = firDownloadURLForFB9 as? String
self.firDownloadURLForFB10 = firDownloadURLForFB10 as? String
self.firDownloadURLForPH1 = firDownloadURLForPH1 as? String
self.firDownloadURLForPH2 = firDownloadURLForPH2 as? String
}
}
For some reason doing virtually the same thing when accessing a specific set of filters worked. Here's the working version of a very similar task and instruction:
var filterSet:FilterSet!
override func viewDidLoad() {
super.viewDidLoad()
filterSetRef.queryOrdered(byChild: "uid").queryEqual(toValue: "aRandomUserID6388").observe(.value, with:{snapshot
in
print("snapshot.value is \(snapshot.value!)")
for item in snapshot.children {
let filterSet = FilterSet(snapshot: item as! FIRDataSnapshot)
ageRangeFilterDeclined = filterSet!.declinedAgeRange!
maxAgeMatch = filterSet!.maxAge!
minAgeMatch = filterSet!.minAge!
genderPref = filterSet!.genderPreference!
includeFBFriendsInMatchResults = filterSet!.includeFBFriends!
includeSportingEvents = filterSet!.sportingEvents!
includeHiking = filterSet!.hiking!
includeMiscellaneous = filterSet!.misc!
includeMuseumsOrArtGalleries = filterSet!.museumsAndArtGalleries!
includePlayMusic = filterSet!.music!
includePlaySports = filterSet!.playingSports!
includeStudyPartner = filterSet!.studyPartner!
includeDancing = filterSet!.dancing!
includeTheatre = filterSet!.theatre!
includeConcerts = filterSet!.concerts!
includeRunningBuddy = filterSet!.running!
includeGames = filterSet!.games!
maxDistanceFilterDeclined = filterSet!.maxDistanceDeclined!
maxDistance = filterSet!.maximumDistance!
}
})
}
}
Here's the FilterSet class that gets successfully populated then referenced, unlike what happens with the Profile class:
import UIKit
import Firebase
class FilterSet: NSObject{
var uID: String!
var declinedAgeRange: Bool!
var genderPreference: String!
var includeFBFriends: Bool!
var sportingEvents: Bool!
var hiking: Bool!
var misc: Bool!
var museumsAndArtGalleries: Bool!
var music: Bool!
var playingSports: Bool!
var running: Bool!
var studyPartner: Bool!
var dancing: Bool!
var theatre: Bool!
var concerts: Bool!
var games: Bool!
var maxDistanceDeclined: Bool!
var maximumDistance: Int!
var maxAge: Int!
var minAge: Int!
var filterSetKey: String!
var filterRef: FIRDatabaseReference!
init?(snapshot: FIRDataSnapshot) {
guard let dict = snapshot.value as? [String: Any] else
{ return nil }
guard let uID = dict["uid"] else { return nil }
guard let declinedAgeRange = dict["DeclinedAgeRangeFilter"] else
{ return nil }
guard let genderPreference = dict["GenderPreference"] else
{ return nil }
guard let includeFBFriends = dict["IncludeFBFriendsInMatches"] else
{ return nil }
guard let sportingEvents = dict["IncludeAttendSportingEvent"] else
{ return nil }
guard let hiking = dict["IncludeHikingPartner"] else
{ return nil }
guard let misc = dict["IncludeMiscellaneous"] else
{ return nil }
guard let museumsAndArtGalleries =
dict["IncludeMuseumsAndArtGalleries"] else { return nil }
guard let music = dict["IncludePlayingMusic"] else { return nil }
guard let playingSports = dict["IncludePlayingSports"] else
{ return nil }
guard let running = dict["IncludeRunningBuddy"] else
{ return nil }
guard let studyPartner = dict["IncludeStudyPartner"] else
{ return nil }
guard let dancing = dict["IncludeDancing"] else { return nil }
guard let concerts = dict["IncludeConcerts"] else { return nil }
guard let theatre = dict["IncludeTheatre"] else { return nil }
guard let games = dict["IncludeGames"] else { return nil }
guard let maxDistanceDeclined =
dict["MaxDistanceFilterDeclined"] else { return nil }
guard let maximumDistance = dict["MaxDistanceOfPostings"] else
{ return nil }
guard let maxAge = dict["MaximumMatchAge"] else
{ return nil }
guard let minAge = dict["MinimumMatchAge"] else { return nil }
self.uID = uID as! String
self.declinedAgeRange = declinedAgeRange as! Bool
self.genderPreference = genderPreference as! String
self.includeFBFriends = includeFBFriends as! Bool
self.sportingEvents = sportingEvents as! Bool
self.hiking = hiking as! Bool
self.misc = misc as! Bool
self.museumsAndArtGalleries = museumsAndArtGalleries as! Bool
self.music = music as! Bool
self.playingSports = playingSports as! Bool
self.running = running as! Bool
self.studyPartner = studyPartner as! Bool
self.dancing = dancing as! Bool
self.concerts = concerts as! Bool
self.theatre = theatre as! Bool
self.games = games as! Bool
self.maxDistanceDeclined = maxDistanceDeclined as! Bool
self.maximumDistance = maximumDistance as! Int
self.maxAge = maxAge as! Int
self.minAge = minAge as! Int
}
}
I also tried to extract the data from FIR Database using:
if let dict = snapshot.value as? Dictionary<String, AnyObject> {
otherUserName = dict["userName"], etc.
The compiler tells me the desired values are present and readable milliseconds before then crashing upon saying it unexpectedly found a nil value for "profile!userId!" or whichever of the three profile statements I have it read first. (I edit out the extraneous values it also said were in this snapshot):
snapshot.value is {
"-Khh__kC9V9mnT1SAbGh" = {
URLofMediumFBProfPic = "https://scontent.xx.fbcdn.net/v/t1.0-1/p100x100/10665301_10204284275524944_7824974439027842885_n.jpg?oh=237544b1350b5759e963c2f5b8234f69&oe=594E1F1";
name = Michael;
uid = aRandomUserID6388;
};
}
I also tried to have these values read after implementing a 3-second delay, but that didn't work.
I don't see any differences between my working code and my non-working code. I am out of ideas for how to solve this problem. Anyone have any idea how my working and non-working examples differ? Sorry for there being so much code above...
changing the profile object to:
init?(snapshot: FIRDataSnapshot) {
let dict = snapshot.value as! [String: Any]// else { return nil }
let userId = dict["uid"] as! String// else { return nil }
let firstName = dict["name"] as! String //else { return nil }
let age = dict["age"] as! Int //else { return nil }
let birthday = dict["birthday"] as! String //else { return nil }
let gender = dict["gender"] as! String //else { return nil }
let education = dict["education"] as! String //else { return nil }
let thisIsMyFun = dict["bodyOfThisIsMyFun"] as! String // else { return nil }
let iAm = dict["bodyOfIAM"] as! String //else { return nil }
let location = dict["locationOfUser"] as! String //else { return nil }
let userLat = dict["latitudeOfUser"] as! Double //else { return nil }
let userLong = dict["longitudeOfUser"] as! Double //else { return nil }
let firStorageNameForFB1 = dict["firStorageNameForFBPhoto1"] as! String //else { return nil }
let firStorageNameForFB2 = dict["firStorageNameForFBPhoto2"] as! String //else { return nil }
self.firStorageNameForFB3 = dict["firStorageNameForFBPhoto3"] as? String
self.firStorageNameForFB4 = dict["firStorageNameForFBPhoto4"] as? String
self.firStorageNameForFB5 = dict["firStorageNameForFBPhoto5"] as? String
self.firStorageNameForFB6 = dict["firStorageNameForFBPhoto6"] as? String
self.firStorageNameForFB7 = dict["firStorageNameForFBPhoto7"] as? String
self.firStorageNameForFB8 = dict["firStorageNameForFBPhoto8"] as? String
self.firStorageNameForFB9 = dict["firStorageNameForFBPhoto9"] as? String
self.firStorageNameForFB10 = dict["firStorageNameForFBPhoto10"] as? String
self.firStorageNameForPH1 = dict["firStorageNameForPHPhoto1"] as? String
self.firStorageNameForPH2 = dict["firStorageNameForPHPhoto2"] as? String
let fbDownloadURLForSmallProfPic = dict["URLofSmallFBProfPic"] as! String//else { return nil }
let fbDownloadURLForMediumProfPic = dict["URLofMediumFBProfPic"] as! String//else { return nil }
let fbDownloadURLForLargeProfPic = dict["URLofLargeFBProfPic"] as! String// else { return nil }
let firDownloadURLForFB1 = dict["firDownloadURLStringForFBPic1"] as! String// else { return nil }
let firDownloadURLForFB2 = dict["firDownloadURLStringForFBPic2"] as! String// else { return nil }
self.firDownloadURLForFB3 = dict["firDownloadURLStringForFBPic3"] as? String
self.firDownloadURLForFB4 = dict["firDownloadURLStringForFBPic4"] as? String
self.firDownloadURLForFB5 = dict["firDownloadURLStringForFBPic5"] as? String
self.firDownloadURLForFB6 = dict["firDownloadURLStringForFBPic6"] as? String
self.firDownloadURLForFB7 = dict["firDownloadURLStringForFBPic7"] as? String
self.firDownloadURLForFB8 = dict["firDownloadURLStringForFBPic8"] as? String
self.firDownloadURLForFB9 = dict["firDownloadURLStringForFBPic9"] as? String
self.firDownloadURLForFB10 = dict["firDownloadURLStringForFBPic10"] as? String
self.firDownloadURLForPH1 = dict["firDownloadURLStringForPHPic1"] as? String
self.firDownloadURLForPH2 = dict["firDownloadURLStringForPHPic2"] as? String
self.activePostID1 = dict["FirstActivePostID"] as? String
self.activePostID2 = dict["SecondActivePostID"] as? String
self.activePostID3 = dict["ThirdActivePostID"] as? String
self.activePostID4 = dict["FourthActivePostID"] as? String
self.activePostID5 = dict["FifthActivePostID"] as? String
self.activePostID6 = dict["SixthActivePostID"] as? String
self.userId = userId as! String
self.firstName = firstName as! String
self.age = age as! Int
self.birthday = birthday as! String
self.gender = gender as! String
self.education = education as! String
self.thisIsMyFun = thisIsMyFun as! String
self.iAm = iAm as! String
self.location = location as! String
self.userLat = userLat as! Double
self.userLong = userLong as! Double
self.firStorageNameForFB1 = firStorageNameForFB1 as! String
self.firStorageNameForFB2 = firStorageNameForFB2 as! String
self.firStorageNameForFB3 = firStorageNameForFB3 as? String
self.firStorageNameForFB4 = firStorageNameForFB4 as? String
self.firStorageNameForFB5 = firStorageNameForFB5 as? String
self.firStorageNameForFB6 = firStorageNameForFB6 as? String
self.firStorageNameForFB7 = firStorageNameForFB7 as? String
self.firStorageNameForFB8 = firStorageNameForFB8 as? String
self.firStorageNameForFB9 = firStorageNameForFB9 as? String
self.firStorageNameForFB10 = firStorageNameForFB10 as? String
self.firStorageNameForPH1 = firStorageNameForPH1 as? String
self.firStorageNameForPH2 = firStorageNameForPH2 as? String
self.fbDownloadURLForSmallProfPic = fbDownloadURLForSmallProfPic as! String
self.fbDownloadURLForMediumProfPic = fbDownloadURLForMediumProfPic as! String
self.fbDownloadURLForLargeProfPic = fbDownloadURLForLargeProfPic as! String
self.firDownloadURLForFB1 = firDownloadURLForFB1 as! String
self.firDownloadURLForFB2 = firDownloadURLForFB2 as! String
self.firDownloadURLForFB3 = firDownloadURLForFB3 as? String
self.firDownloadURLForFB4 = firDownloadURLForFB4 as? String
self.firDownloadURLForFB5 = firDownloadURLForFB5 as? String
self.firDownloadURLForFB6 = firDownloadURLForFB6 as? String
self.firDownloadURLForFB7 = firDownloadURLForFB7 as? String
self.firDownloadURLForFB8 = firDownloadURLForFB8 as? String
self.firDownloadURLForFB9 = firDownloadURLForFB9 as? String
self.firDownloadURLForFB10 = firDownloadURLForFB10 as? String
self.firDownloadURLForPH1 = firDownloadURLForPH1 as? String
self.firDownloadURLForPH2 = firDownloadURLForPH2 as? String
self.activePostID1 = activePostID1 as? String
self.activePostID2 = activePostID2 as? String
self.activePostID3 = activePostID3 as? String
self.activePostID4 = activePostID4 as? String
self.activePostID5 = activePostID5 as? String
self.activePostID6 = activePostID6 as? String
}
This results in the original crashing function creating optional values that when forced unwrapped give me the desired values. Not sure why exactly the variables are defined as optional values given that they were defined as non-optional type. Regardless, this somehow solved my problem of not being able to extract needed values.
Look at the init of Profile. You expect optional values (like firStorageNameForFB3) but you are using
guard let firStorageNameForFB3 = dict["firStorageNameForFBPhoto3"] else { return nil }
So every time firStorageNameForFB3 is nil; profile will also be nil.
Try change the init of optional values in your model to:
init?(snapshot: FIRDataSnapshot) {
// ...
self.firStorageNameForFB3 = dict["firStorageNameForFBPhoto3"] as? String
// ...
}
and remove the guard let for this values.

Writing to DB failed?

I'm trying to write 2 data to db.
#IBAction func show(button: UIButton) {
let userRef = self.dataBaseRef.child("users/\(FIRAuth.auth()!.currentUser!.uid)")
userRef.observe(.value, with: { (snapshot) in
let user = User(snapshot: snapshot)
let currentUser = user.email
let request = Requests(requestBy: user.email!,
requestTo: self.email!)
let contactRef = self.ref.child(currentUser! + "--" + self.email!)
contactRef.setValue(request.toAnyObject())
self.items.append(request)
print(request)
}) { (error ) in
print(error.localizedDescription)
}
self.dismiss(animated: true, completion: nil);
}
items is an array
var items: [Requests] = []
user.email and self.email! isn't empty I printed it.
request file looks
struct Requests {
let key: String
let requestBy: String
let requestTo: String
let ref: FIRDatabaseReference?
init(requestBy: String, requestTo: String, key: String = "") {
self.key = key
self.requestBy = requestBy
self.requestTo = requestTo
self.ref = nil
}
init(snapshot: FIRDataSnapshot) {
key = snapshot.key
let snapshotValue = snapshot.value as! [String: AnyObject]
requestBy = snapshotValue["requestBy"] as! String
requestTo = snapshotValue["requestTo"] as! String
ref = snapshot.ref
}
func toAnyObject() -> Any {
return [
"requestBy": requestBy,
"requestTo": requestTo
]
}
}
and I'm getting error - unexpectedly found nil while unwrapping an Optional value
According to what I'm seeing in your posted code, you create a request but never assign a value to the ref property. However, it is not clear since we cannot see where it crashes or when is it really used.
Also, assuming self.ref is an optional (as you've been handled that way in your visible code) then this could be the problem:
let contactRef = self.ref.child
you should first check if you can unwrap that optional, like:
if let realRef = self.ref {
realRef.child(currentUser! + "--" + self.email!)
}
let currentUser = user.email //this is not an optional
let request = Requests(requestBy: user.email!,
requestTo: self.email!)
contactRef = self.ref.child(currentUser! + "--" + self.email!)
currentUser! doesn't need to be unwrapped.

Swift Firebase Access child snapshot data

I am currently trying to access data from a child snapshot in Swift. Here is my code that I have (which worked before the Swift 3/Firebase update):
if let achievements = snapshot1.childSnapshotForPath("Achievements").children.allObjects as? [FIRDataSnapshot] {
if achievements.count != 0 {
if let val = achievements[0].value!["somevalue"] as? Int {
self.dict["somevalue"] = val
}
}
So what I am trying to do here, is to create a variable of a child snapshot (achievements), and access child snapshot data from it. The achievements[0] will simply return the very first value. However, this doesn't seem to work. How should I approach this?
I am currently doing this inside a snapshot already (of 'observeType:.ChildAdded')
My Firebase DB looks like this:
Achievements{
randomId1 {
somevalue : somevalue
}
randomId2 {
somevalue2 : somevalue2
}
}
Updated code:
func loadData() {
ref.child("Players").observe(FIRDataEventType.childAdded) { (snapshot:FIRDataSnapshot) in
if let value = snapshot.value as? [String:AnyObject], let username = value["Username"] as? String {
}
if let value = snapshot.value as? [String:AnyObject], let ranking = value["Rank"] as? String {
}
if let childSnapshot = snapshot.childSnapshot(forPath: "Achievements").children.allObjects as? [FIRDataSnapshot] {
if childSnapshot.count != 0 {
if let achievement1 = childSnapshot[0].value!["Rookie"] as? String {
print(achievement1)
}
}
}
}
}
JSON Tree:
Players {
PlayerID {
Username
Rank
Achievements {
Rookie: yes
}
}
Try :-
if let childSnapshot = snapshot.childSnapshot(forPath: "Achievements") as? FIRDataSnapshot{
if let achievementDictionary = childSnapshot.value as? [String:AnyObject] , achievementDictionary.count > 0{
if let achieveMedal = achievementDictionary["Rookie"] as? String {
print(achieveMedal)
}
}
}

Resources