Xcode 8 Firebase Error - ios

I'm having a bit of issue implying my code. I'm trying to build a chat app and I'm getting one lousy error. I was wondering if anyone could help me fix it or tell me what I'm doing wrong?
import UIKit
import Firebase
class LoginViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
if nameField?.text != "" { // 1
FIRAuth.auth()?.signInAnonymously(completion: { (user, error) in // 2
if let err = error { // 3
print(err.localizedDescription)
return
}
self.performSegue(withIdentifier: "LoginToChat", sender: nil) // 4
})
}
}

I think as textfield outlet is always optional, so you are getting this error.Take value of textfield in variable then compare it. Let say code as below:
let stringTextValue = nameField.text! as String
if stringTextValue != "" {

Related

Initial navigation view controller of AuthUI not working under Xcode 10.2

I recently upgraded to Xcode 10.2.
Before the upgrade I could use the stock Initial Navigation View Controller of AuthUI from Firebase Realtime Database, I could sign up and login to Firebase without problems, now I get a "welcome" screen only.
I'm using the same code as before. (note that the authentification works in my old project even with Xcode 10.2, I cannot make any new projects using the Initial Navigation View Controller of AuthUI)
I tried the same code that worked with Xcode 10 and Swift 4.2
I even set up another test project from zero to diagnose the problem, I reached out to the Firebase team about this, I'm posting my question here in the meantime, hoping for a fast answer.
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
#IBAction func loginTapped(_ sender: Any) {
let authUI = FUIAuth.defaultAuthUI()
guard authUI != nil else { return }
authUI?.delegate = self
let authViewController = (authUI?.authViewController())!
present(authViewController, animated: true, completion: nil)
}
}
extension ViewController: FUIAuthDelegate {
func authUI(_ authUI: FUIAuth, didSignInWith authDataResult: AuthDataResult?, error: Error?) {
guard error == nil else { return }
performSegue(withIdentifier: "goHome", sender: self)
}
}
The problem is that the authentification page won't load up, I cannot sign up/login; therefore the performSegue never fires.
Add this to your code :
authUI?.providers = [FUIEmailAuth()]
Plus, you have modify the pod file and add: pod 'FirebaseUI/Email' if you are using email.

Referencing IBOutlet in another View Controller

So, I have been having some major trouble figuring this out and I have searched extensively for a solution but I surprisingly could not find one. I am attempting to create a multiple page (5, to be exact) Sign-Up for users.
I'll start off by showing you the layout of page 1 and 5 (since solving that issue will solve the issue for page 2-4):
Sign Up Page #1
Sign Up Page #5
As you may see (from the page control dots), I am using a page view controller to allow users to scroll from page to page. What I am trying to accomplish is giving the user the ability to enter their sign-up information in pages 1-5 before submitting it all at once (which can be located on page 5).
Here is the current code I am using for page #1:
class SignUpInfoViewController: UIViewController {
#IBOutlet weak var emailTextField: UITextField!
#IBOutlet weak var passwordTextField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Here is the current code I am using for page #5:
class TermsOfUseViewController: UIViewController {
let minPasswordCharCount = 6
#IBAction func signUpAction(_ sender: Any) {
let providedEmailAddress = SignUpInfoViewController().emailTextField.text!
let providedPassword = SignUpInfoViewController().passwordTextField.text!
let trimmedPassword = providedPassword.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)
if !(validEmail(enteredEmail: providedEmailAddress) && validPassword(enteredPassword: trimmedPassword)) {
invalidCredentialsAlert()
}
else {
FIRAuth.auth()?.createUser(withEmail: providedEmailAddress, password: providedPassword) { user, error in
if error == nil {
FIRAuth.auth()!.signIn(withEmail: providedEmailAddress,
password: providedPassword)
}
else {
let alertController = UIAlertController(title: "Error", message: error?.localizedDescription, preferredStyle: .alert)
let defaultAction = UIAlertAction(title: "OK", style: .cancel, handler: nil)
alertController.addAction(defaultAction)
self.present(alertController, animated: true, completion: nil)
}
}
}
}
// Email is valid if it has a standard email format
func validEmail(enteredEmail: String) -> Bool {
let emailFormat = "[A-Z0-9a-z._%+-]+#[A-Za-z0-9.-]+\\.[A-Za-z]{2,64}"
let emailPredicate = NSPredicate(format:"SELF MATCHES %#", emailFormat)
return emailPredicate.evaluate(with: enteredEmail)
}
// Password is valid if it is not empty or greater than a specified number of characters
func validPassword(enteredPassword: String) -> Bool {
if (enteredPassword != "" && enteredPassword.characters.count >= minPasswordCharCount) {
return true
}
return false
}
In the TermsOfUseViewController class, I am attempting to use the emailTextField and passwordTextField outlets from the SignUpInfoViewController, but I am receiving the following error:
fatal error: unexpectedly found nil while unwrapping an Optional value
I debugged the error and saw that the emailTextField property from SignUpInfoViewController is nil and so force unwrapping it will cause the app to crash (Note: I have correctly connected the IBOutlets to the SignUpInfoViewController, so no issue there).
How can I safely transfer the usage of the IBOutlets from the SignUpInfoViewController class to the TermsOfUseViewController class without it crashing? In other words, how can I make it to where the IBOutlets are no longer nil when I reference them in the TermsOfUseViewController class?
Thank you!
That is a perfect scenario for delegate pattern
protocol SignUpProtocol: class {
func didProvideUserData(username: String ,password: String)
}
In your signup class declare a delegate: public weak var delegate:SignUpProtocol?
I am assuming when the user has provided the require info, they need to press some button to go to the next step: Thus in that button you should raise the delegate
#IBAction func nextButton(sender:UIButton) {
guard let username = usernameTextfield?.text, let password = passwordTextField?.text, else { fatalError("textfields were empty") }
if delegate != nil { // this saying when someone is listening to me, I will expose any method associated to me
delegate?.didProvideUserData(username:username, password:password) // passing the username and password from textfield
}
}
if you don't have a button, then look at property observer, where you could have some property
var didFulfill:Bool? = nil {
didSet {
if didFulfill != nil && didFulfill == true {}
// here you check if your textfields are sets then raise the delegate
}
}
set this property didFulfill = when both textfields are not empty :)
Now in your Terms class, just subscribe to that delegate
class TermsOfUseViewController: UIViewController, SignUpProtocol {
var signUpVc: SignUpInfoViewController?
override func viewDidLoad() {
super.viewDidLoad()
signUpVc = SignUpInfoViewController()
signUpVc?.delegate = self
}
func didProvideUserData(username: String, password:String) {
// there is your data
}
}
You have to take in account that you don't have all references for all UIPageViewControllers all the time. That being said, I would suggest either to keep object in UIPageViewController with updated information or using Singleton Pattern to use it to store info into it and later use it. UIPageViewController are being reused and you might have one before and one after and relying onto having them would be wrong.
You can use UIPageViewController as self.parentViewController or something like that.

How to structure code to deal with asynchronous Firebase snapshot? [duplicate]

This question already has answers here:
Returning method object from inside block
(3 answers)
Closed 5 years ago.
I have an problem that I can not solve. A lot of questions are in JS and I don't really understand them.
I'm using Firebase as my database for my IOS app and Swift. Here is my situation:
I have a class file that contains functions that can retrieve values in my database. I'm calling these functions in some viewControllers.
The values retrieved by these functions are immediately used in these viewControllers.
My problem is that my app crash because of nil values returned by the class file functions. This happen because of the asynchronous Firebase snapshot.
The variables assumed to contain the values are used before their value is assigned => My app crash, or printed values are nil.
Then my question is simple: How can I structure my code to avoid this issue? I already tried completions, but that's not working for me: functions are still asynchronous.
Here is one of my function in the class file:
func initAverageMark(completionHandler: #escaping (_ mark: Double) -> ()) {
let userRef = ref.child("users").child((user?.uid)!).child("mark")
userRef.observeSingleEvent(of: .value, with: { (snapshot) -> Void in
if let mark: Double = snapshot.value as? Double {
completionHandler(mark)
}
}) { (error) in
print(error.localizedDescription)
}
}
One of my viewController code:
private var totalAsks: Double!
override func viewDidLoad() {
super.viewDidLoad()
initInfos()
}
func initInfos() {
mainUser().initTotalAsks{ total in
self.totalAsks = total
}
initLabels()
}
func initLabels() {
totalAsksLabel.text = " \(totalAsks!)" // it crashs here
}
Assuming you'd want to set some label or something in your viewController to the value of mark you'd do it like this.
mainUser().initTotalAsks { mark in
self.totalAsksLabel.text = " \(mark)"
}
Edit
Or if you absolutely want to use that Double.
private var totalAsks: Double? = nil {
didSet {
initLabels()
}
}
override func viewDidLoad() {
super.viewDidLoad()
initInfos()
}
func initInfos() {
mainUser().initTotalAsks{ total in
self.totalAsks = total
}
}
func initLabels() {
guard totalAsks != nil else {
return
}
totalAsksLabel.text = " \(totalAsks!)"
}

Getting a picture from firebase storage

I'm creating an iOS application which has many pictures on it. I therefore decided to use a database to store the pictures on and retrieve from the database. I have inputted the pictures manually through the Firebase site.
Here is the code I currently have:
import UIKit
import Firebase
class F_A_1: UIViewController {
#IBOutlet weak var imageViewer: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
let database = FIRDatabase.database().reference()
let storage = FIRStorage.storage().reference()
let animalref = FIRStorage.storage().reference().child("animal/bird.png")
animalref.dataWidthMaxSize(1*1000*1000){ (date, error) in
if error = nill {
print(data)
self.imageViewer.image = UIImage(data: data!)
} else {
print(error?.localizedDescription)
}
}
}
This is giving me an error which I cannot fix.
Thanks in advance :)
import UIKit
import Firebase
class F_A_1: UIViewController {
#IBOutlet weak var imageViewer: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
let database = FIRDatabase.database().reference()
let storage = FIRStorage.storage().reference()
let animalref = FIRStorage.storage().reference().child("animal/bird.png")
func nameThisWhatYouWant() {
animalref.data(withMaxSize: 1*1000*1000) { (data, error) in
if error == nil {
print(data)
} else {
print(error?.localizedDescription)
}
}
}
}
i have tried this but it gives a sigbart error
Well I have never worked with Firebase and don't know how to go about connecting it, but you have an issue where you are doing logic in your app.
class F_A_1: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
let database = FIRDatabase.database().reference()
let storage = FIRStorage.storage().reference()
let animalref = FIRStorage.storage().reference().child("animal/bird.png")
func nameThisWhatYouWant() {
animalref.dataWidthMaxSize(1*1000*1000){ (date, error) in
if error = nill {
print(data)
self.imageViewer.image = UIImage(data: data!)
} else{
print(error?.localizedDescription)
}
}
}
}
I added a function called nameThisWhatYouWant where you should be handling your data, and sending it off to Firebase. As far as working with Firebase, go here to see how to set up Firebase by working with Cocoa Pods, then allowing you to import Firebase. As far as actually being able to send your data off, they have tons of documentation and examples to follow to read through.
You are comparing the error to nill instead of nil.
Where are you getting your error?

Error with PFObject does not have a member named 'Contains' (SWIFT Xcode Parse)

So I'm trying to create a registration page with availability by Zip Code. For instance, a user can only register if the service is available in their area (zip code).
This is my current code, it checks what the user typed in the TextField and compared is to a string in my Parse database, if it matches; they can sign up and a new viewController will open up.
Except I have 1 error only.
class checkAvailability: UIViewController, UITextFieldDelegate {
#IBOutlet weak var zipCode: UITextField!
#IBAction func checkAvailBtn(sender: AnyObject) {
checkZip()
}
func checkZip() {
let usersZipCode = zipCode.text
let query = PFQuery(className:"zipCodes")
query.findObjectsInBackgroundWithBlock {
(objects: [AnyObject]?, error: NSError?) -> Void in
if error == nil {
// The find succeeded.
print("Successfully retrieved \(objects!.count) zip codes.")
// Do something with the found objects
if let zipCodes = objects as? [PFObject] {
if zipCodes.contains({ $0["zipCodes"] as! String == usersZipCode }) { **THIS IS THE LINE WITH THE ERROR**
println()("your in!") // transition to the new screen
performSegueWithIdentifier("beginSignUp", sender: self)
}
else {
println("your out.") // do whatever
}
}
} else {
// Log details of the failure
print("Error: \(error!) \(error!.userInfo)")
}
}
}
The error is:
[PFObject] does not have a member named 'contains'.
Any help is appreciated. Thank you.
The contains method is only available in Swift 2 within the Xcode 7 environment. You're using Swift 1.2, and there's no contains there.
Solution: Compile your code in Xcode 7 beta

Resources