Why would this swift code still be performing the segue? - ios

I have a conditional segue set up that will perform the segue set up the following way:
override func viewDidAppear(animated: Bool) {
if PFUser.currentUser() != nil{ //if the user is logged in previously
self.performSegueWithIdentifier("AlreadySignedIn", sender: self)
print(PFUser.currentUser()?.username)
}
Even deleting all users from the database (Parse), the segue is still performed. I don't think the problem is with the syntax of this particular code, but does anyone have any ideas what might be causing this?

PFUser.currentUser() is not aware about the users that you have in your DB.
when you log in to Parse via parse ios SDK. the parse IOS SDK save the currentUser instance on your disk and when you specify PFUser.currentUser() the parse IOS SDK check if the user was logged in before (by checking if it is stored on the disk). if you want that the PFUser.currentUser() will return nil you must call PFUser.logout() function. this function will clear the current logged in user.

Related

firestore collection path giving bugs with constants value and String value

So my goal is to get rid of these bugs completely. I am in a dilemma where each decision leads to a bug.
The first thing I can do that eventually becomes an issue is use a String-interpolated collection path in all my query functions like so:
func getEventName() {
listener = db.collection("school_users/\(user?.uid)/events").order(by: "time_created", descending: true).addSnapshotListener(includeMetadataChanges: true) { (querySnapshot, error) in
if let error = error {
print("There was an error fetching the data: \(error)")
} else {
self.events = querySnapshot!.documents.map { document in
return EventName(eventName: (document.get("event_name") as! String))
}
self.tableView.reloadData()
}
}
}
The thing with this is, when I run the app on the simulator, I am restricted from pressing buttons and then sometimes I can press them and then sometimes they get restricted again. This bug is so confusing because it makes no sense where it springs from.
The other issue is I can use a Constants value in all the query functions in my collections path.
static let schoolCollectionName = "school_users/\(user?.uid)/events"
This is nested in a Firebase struct within the Constants struct. In order to keep Xcode from giving errors I create a let users = Auth.auth().currentUser variable outside the Constants struct. The issue with this value is that when I put that in all of my query functions collection paths, all the buttons are accessible and selectable all the time, but when a user logs out and I log in as a new user, the previous user's data shows up in the new user's tableview.
It would obviously make more sense to use the Constants value because you prevent typos in the future, but I can't figure out how to get rid of the bug where the old user's data shows up in the new user's tableview. Thanks in advance.
The user id should definitely not be a constant. What it sounds like is that right now, you have no reliable way to change users -- your setup probably depends on which user is logged in at app startup, since that's where your variable gets set.
I would do something more like this:
func getEventName() {
guard let user = Auth.auth().currentUser else {
//handle the fact that you don't have a user here -- don't go on to the next query
return
}
listener = db.collection("school_users/\(user.uid)/events").order(by: "time_created", descending: true).addSnapshotListener(includeMetadataChanges: true) { (querySnapshot, error) in
Note that now, user.uid in the interpolated path doesn't have the ? for optionally unwrapping it (which Xcode is giving you a warning for right now). It will also guarantee that the correct query is always made with the currently-logged-in user.
Regarding being able to press the buttons, that sounds like an unrelated issue. You could run your app in Instruments and check the Time Profiler to see if you have long-running tasks that are gumming up the main/UI thread.

getting innerText from ID element with swift not working with webView

I am using swift 4.2 so I am not sure if my code is outdated because many of the examples are not for the latest.
I have been trying many of the examples I have found here on stack but it seems they are outdated because of many references not valid working anymore.
I am trying to get the innerText of an element with a particular ID. Unfortunately I produce no results in successfully getting the value. Then I am trying to take result and put it in Firebase. If I use something like "test" instead of result it works fine, but I need result
Here is my code.
override func viewDidLoad() {
super.viewDidLoad()
ref = Database.database().reference()
webView.evaluateJavaScript("document.getElementById('get_this_user').innerText") { (result, error) in
self.ref?.child("users").child("usernames").setValue(["get_this_user": result])
}
}

SFAuthenticationViewController issue with Google on iOS 11

I implemented authentication using Google Sign In and everything works correctly. However, if the user taps Cancel on the Google-generated dialog box that asks the user "Foo Wants to Use "google.com" to Sign In", the app crashes with a 'Attempting to load the view of a view controller while it is deallocating is not allowed and may result in undefined behavior: SFAuthenticationViewController' error.
I thought maybe I did not implement an optional function in the GIDSignInUIDelegate but I have them implemented and there is nothing in the Google documentation that talks about this possibility (https://firebase.google.com/docs/auth/ios/google-signin).
Does anyone know what I am missing to handle a Cancel press?
In my case I was doing popToRoot back navigation, so I have been set delegate and presentingViewController on viewDidLoad() but actually when I come back there is no reference for GIDSignIn.sharedInstance().delegate and GIDSignIn.sharedInstance().presentingViewController.
Simply I wrote code on google login button action:
#IBAction func buttonHandlerGoogle(_ sender: Any) {
//===These lines added for the reference=========
GIDSignIn.sharedInstance().delegate = self
GIDSignIn.sharedInstance().presentingViewController = self
//===============================================
GIDSignIn.sharedInstance().signIn()
}

Firebase addStateDidChangeListener

I am pretty new to Firebase. I am trying to check if the user is logged in or not, and by referring to the Firebase doc, the recommended way of doing it would be adding a FIRAuthStateDidChangeListenerHandle.
My code is as follows:
handle = FIRAuth.auth()?.addStateDidChangeListener({ (auth, user) in
//here, we add code to see if we are supposed to be loggin or not
print("hello world")
if user != nil{
self.isLogin = true
}else{
self.isLogin = false
}
})
However, after I checked, it seems that FirAuth.auth() is a nil and the entire block is not called at all.
Any one knows what is wrong here?
This looks like an improperly set up Firebase. Did you follow all the steps here? Specifically, did you, in your AppDelegate, call FIRApp.configure()? Without this configuration call your FIRAuth would likely be nil.

What makes a user discoverable to CKDiscoverAllUserIdentitiesOperation?

I am trying to discover contacts for a user with the code below (the code is in an implementation of a UITableViewController. I put breakpoints in both code blocks, and I determined that the the userIdentityDiscoveredBlock is not called while the completionBlock is called. This indicates that the operation is being run as expected, it just isn't finding any contacts.
I am running on the simulator, but I verified that the simulator has synced all my iCloud contacts (opening the Contacts app on the simulator shows all my contacts).
override func viewDidLoad() {
super.viewDidLoad()
let op = CKDiscoverAllUserIdentitiesOperation()
op.discoverAllUserIdentitiesCompletionBlock = { error -> Void in
// reload my data table
}
op.userIdentityDiscoveredBlock = { user -> Void in
if user.hasiCloudAccount {
self.iCloudUsers.append(user)
} else {
self.nonICloudUsers.append(user)
}
}
CKContainer.default().add(op)
}
So my question is this - Is there something else that has to be done in order to discover contacts? Is this a simulator issue?
I searched the documentation and other questions but I can't seem to find information on this given the operation is new to iOS 10.
There's quite a bit that must be done before CKDiscoverAllUserIdentitiesOperation will return any results.
First, each user of your app must grant permission to be looked up by email. Your app makes this request using CKContainer requestApplicationPermission.
Each user of your app must also be logged into an iCloud account. iCloud Drive must also be enabled by the user.
And lastly, for CKDiscoverAllUserIdentitiesOperation to return any users, the person must have contacts with email addresses that match other users that completed all of the previous steps.

Resources