firebase analytics error when preforming segue - ios

The app crashes when I perform the segue. I checked if there was any sigbrt errors, but there was not. I think it is firebase analytics from the log. This error was from the log :
terminating with uncaught exception of type NSException.
The code
#IBOutlet weak var email: UITextField!
#IBOutlet weak var password: UITextField!
#IBOutlet weak var adduser: UIButton!
#IBOutlet weak var errormessege: UILabel!
var databaseref = FIRDatabase.database().reference()
override func viewDidLoad() {
super.viewDidLoad()
password.isSecureTextEntry = true
adduser.isEnabled = false
}
#IBAction func didtapcancel(_ sender: Any) {
dismiss(animated: true, completion: nil)
}
#IBAction func didtapadd(_ sender: Any) {
adduser.isEnabled = false
FIRAuth.auth()?.createUser(withEmail: email.text!, password: password.text!, completion: {(user,error) in
if error != nil {
if error!._code == 17999 {
self.errormessege.text = "Invalid email address" }
else {
self.errormessege.text = error?.localizedDescription
}
}
else
{
FIRAuth.auth()?.signIn(withEmail: self.email.text!, password: self.password.text!, completion: {(user,error) in
if (error == nil) {
self.databaseref.child("users").child(user!.uid).child("email").setValue(self.email.text!)
self.performSegue(withIdentifier: "hi", sender: nil)
}
else {
self.errormessege.text = error?.localizedDescription
}
})
}
}
)
}
#IBAction func didtextchange(_ sender: Any) {
if((email.text?.characters.count)!>0){
adduser.isEnabled = true}
else{
adduser.isEnabled = false}
}
#IBAction func did4(_ sender: Any) {
if((password.text?.characters.count)!>0){
adduser.isEnabled = true}
else{
adduser.isEnabled = false}
}

Without more code and the entire scenario in front of me it is hard to specifically nail down what is happening between your code and Firebase. One thing that will significantly help you though in tracking down this error is to validate the data you are pulling out of your #IBOutlets each steps of the way. That way your program is not force unwrapping these objects and leaving opening up your code to risk.
#IBOutlet weak var email: UITextField!
#IBOutlet weak var password: UITextField!
#IBOutlet weak var adduser: UIButton!
#IBOutlet weak var errormessege: UILabel!
var databaseref = FIRDatabase.database().reference()
override func viewDidLoad() {
super.viewDidLoad()
password.isSecureTextEntry = true
adduser.isEnabled = false
}
#IBAction func didtapcancel(_ sender: Any) {
dismiss(animated: true, completion: nil)
}
#IBAction func didtapadd(_ sender: Any) {
adduser.isEnabled = false
guard let emailText = email.text,
let passwordText = password.text else {
// Handle error safely
print("Error unrapping email text or password text")
return
}
FIRAuth.auth()?.createUser(withEmail: emailText, password: passwordText, completion: { (user,error) in
if error != nil {
if error!._code == 17999 {
self.errormessege.text = "Invalid email address"
} else {
self.errormessege.text = error?.localizedDescription
}
} else {
FIRAuth.auth()?.signIn(withEmail: emailText, password: passwordText, completion: { (user, error) in
if (error == nil) {
guard let uid = user.uid else {
// handle error safely
print("Error with user uid")
return
}
self.databaseref.child("users").child(uid).child("email").setValue(emailText)
self.performSegue(withIdentifier: "hi", sender: nil)
}
else {
self.errormessege.text = error?.localizedDescription
}
})
}
})
}
#IBAction func didtextchange(_ sender: Any) {
guard let emailText = email.text else {
// Return error safely
print("Error unrapping email text")
return
}
if emailText.characters.count> 0 {
adduser.isEnabled = true
} else{
adduser.isEnabled = false
}
}

Related

User variable is nil when creating a user with Firebase

I am following a tutorial and cannot seem to register my user as the user variable in the Firebase .createUser method appears to be nil. Therefore, when I unwrap it, I get an error.
I have read through a lot of the documentation as well as checked many other questions similar to mine but nothing seems to work
import UIKit
import Firebase
import SwiftKeychainWrapper
class ViewController: UIViewController {
#IBOutlet weak var userImgView: UIImageView!
#IBOutlet weak var usernameField: UITextField!
#IBOutlet weak var emailField: UITextField!
#IBOutlet weak var passwordField: UITextField!
var imagePicker: UIImagePickerController!
var selectedImage: UIImage!
override func viewDidLoad() {
super.viewDidLoad()
imagePicker = UIImagePickerController()
imagePicker.allowsEditing = true
imagePicker.delegate = self
}
override func viewDidAppear(_ animated: Bool) {
if let _ = KeychainWrapper.standard.string(forKey: "uid") {
self.performSegue(withIdentifier: "toFeed", sender: nil)
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func setupUser(userUid: String) {
if let imageData = self.userImgView.image!.jpegData(compressionQuality: 0.2) {
let imgUid = NSUUID().uuidString
let metaData = StorageMetadata()
Storage.storage().reference().child(imgUid).putData(imageData, metadata: metaData) { (metadata, error) in
let downloadURL = metadata
let userData = [
"username": self.usernameField.text!,
"userImg": downloadURL!
] as [String : Any]
Database.database().reference().child("users").child(userUid).setValue(userData)
self.performSegue(withIdentifier: "toFeed", sender: nil)
}
}
}
#IBAction func signInPressed(_ sender: Any) {
if let email = emailField.text, let password = passwordField.text {
Auth.auth().signIn(withEmail: email, password: password) { user, error in
if error != nil && !(self.usernameField.text?.isEmpty)! {
Auth.auth().createUser(withEmail: email, password: password) { (user, error) in
self.performSegue(withIdentifier: "toFeed", sender: nil)
let userID = (user?.user.uid)!
self.setupUser(userUid: userID)
KeychainWrapper.standard.set(userID, forKey: "uid")
}
} else {
if let userID = (user?.user.uid) {
KeychainWrapper.standard.set((userID), forKey: "uid")
self.performSegue(withIdentifier: "toFeed", sender: nil)
}
}
}
}
}
#IBAction func getPhoto (_ sender: AnyObject) {
present(imagePicker, animated: true, completion: nil)
}
}
extension ViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
internal func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
if let image = info[.originalImage] as? UIImage {
userImgView.image = image
} else {
print("image wasnt selected")
}
imagePicker.dismiss(animated: true, completion: nil)
}
}
The error I am getting is one the "let userID = (user?.user.uid)!". It is
Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
The completion block for createUser(withEmail:,password:) gets called with either a AuthResult.user or an error. That why, as Joshua commented, you should check if error is nil before accessing any of the user properties.
From the auth quickstart for Swift:
Auth.auth().createUser(withEmail: email, password: password) { authResult, error in
strongSelf.hideSpinner {
guard let user = authResult?.user, error == nil else {
strongSelf.showMessagePrompt(error!.localizedDescription)
return
}
print("\(user.email!) created")
strongSelf.navigationController?.popViewController(animated: true)
}
}

optional key is generated in firebase database

This code is responsible for uploading the text and and the time of the post under an auto generated key of the logged in user it is in the function didtappost in the first line
#IBOutlet weak var post: UIButton!
#IBOutlet weak var newpost: UITextView!
var databaseref = FIRDatabase.database().reference()
var loggedinuser : AnyObject?
override func viewDidLoad()
{
super.viewDidLoad()
self.loggedinuser = FIRAuth.auth()?.currentUser
newpost.textContainerInset = UIEdgeInsetsMake(30, 20, 20, 20)
newpost.text = "what is new?"
newpost.textColor = UIColor.lightGray
}
#IBAction func didtapcancel(_ sender: Any) {
dismiss(animated: true, completion: nil)
}
func textFieldShouldReturn(_ textfield: UITextField) -> Bool {
textfield.resignFirstResponder()
return false
}
#IBAction func didtappost(_ sender: Any) {
if(newpost.text.characters.count>0)
{
let key = databaseref.child("posts").childByAutoId().key
let childupdates = ["/posts/\(self.loggedinuser!.uid)/\(key)/text ": newpost.text,"/posts/\(self.loggedinuser!.uid)/\(key)/time":"\(Date().timeIntervalSince1970)"
] as [String : Any]
self.databaseref.updateChildValues(childupdates)
dismiss(animated: true, completion: nil)
}
}
}

Login Validation from parsed result

I've successfully parsed an result from a SOAP WebServices request I made, by sending in a userName and password.
But now I need to validate this login function and if true segue to a new view programmatically:
let menuPageView = (self.storyboard?.instantiateViewController(withIdentifier: "MenuCentral"))!
self.present(menuPageView, animated: true, completion: nil)
The problem is I don't know how or where to add such validation.
class LoginCentralViewController: UIViewController, SOAPServiceProtocol {
var chave = ChaveWebService().chave()
var soapService : SOAPService?
var resultadoLoginCentral : [LoginCentralModel]!
#IBOutlet weak var txtUsuarioOUTLET: UITextField!
#IBOutlet weak var txtSenhaOUTLET: UITextField!
#IBOutlet weak var btnAcessarOUTLET: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
soapService = SOAPService(delegate: self)
print(chave)
}
#IBAction func btnAcessarACTION(_ sender: Any) {
soapService?.loginCentral(userName: txtUsuarioOUTLET.text!, password: txtSenhaOUTLET.text!, methodName: nomeServico)
UIApplication.shared.isNetworkActivityIndicatorVisible = true
}
func didSuccessRequest(results: XMLIndexer, requestName: String) {
UIApplication.shared.isNetworkActivityIndicatorVisible = false
switch requestName {
case nomeServico:
do{
resultadoLoginCentral = try LoginCentralModel.realizarLoginCentral(results: results)
} catch let error as XMLParseError{
print(error.description)
return
} catch {
print(error)
return
}
print("codigoCliente = ", resultadoLoginCentral[0].codigoCliente)
print("permissoes = " , resultadoLoginCentral[0].permissoes)
break
default:
break
}
}
func didFailRequest(err: String, requestName: String) {
UIApplication.shared.isNetworkActivityIndicatorVisible = false
switch requestName {
case nomeServico:
return
default:
break
}
}
func showAlert() {
let loginAlert = UIAlertController(title: "Central do Assinante", message: "Login/Senha inválidos", preferredStyle: .alert)
let acaoDefault = UIAlertAction(title: "OK", style: .destructive, handler: nil)
loginAlert.addAction(acaoDefault)
present(loginAlert, animated: true, completion: nil)
}
}
You can put your validation code here
do{
resultadoLoginCentral = try LoginCentralModel.realizarLoginCentral(results: results)
//Put here code
// we need to call this in main thread
DispatchQueue.main.sync {
if resultadoLoginCentral.codigoCliente.characters.count > 0 && resultadoLoginCentral.permissoes.characters.count > 0{{
// Login process
}else{
//Show Alert
}
}
}
Hope this helps

App is performing segue automatically (Swift 2.0, Firebase 3)

Been smashing my face against the wall all day trying to upgrade my app to the Firebase 3.x code.
I was having a ton of trouble with updating my original userAuth code and decided to just start from scratch. I haven't really been able to test it though because when I run the app it is calling the segue immediately upon loading the initial VC. Obviously I don't want it to do this and I don't know what is causing it.
I've tried deleting the app from the simulator and when I load it back up I get the same result.
Here is my code for the VC:
import UIKit
import FirebaseAuth
class SignInViewController: UIViewController {
#IBOutlet weak var emailField: UITextField!
#IBOutlet weak var passwordField: UITextField!
override func viewDidAppear(animated: Bool) {
if let user = FIRAuth.auth()?.currentUser {
self.signedIn(user)
}
}
#IBAction func didTapSignIn(sender: AnyObject) {
// Sign In with credentials.
let email = emailField.text
let password = passwordField.text
FIRAuth.auth()?.signInWithEmail(email!, password: password!) { (user, error) in
if let error = error {
print(error.localizedDescription)
return
}
self.signedIn(user!)
}
}
#IBAction func didTapSignUp(sender: AnyObject) {
let email = emailField.text
let password = passwordField.text
FIRAuth.auth()?.createUserWithEmail(email!, password: password!) { (user, error) in
if let error = error {
print(error.localizedDescription)
return
}
self.setDisplayName(user!)
}
}
func setDisplayName(user: FIRUser) {
let changeRequest = user.profileChangeRequest()
changeRequest.displayName = user.email!.componentsSeparatedByString("#")[0]
changeRequest.commitChangesWithCompletion(){ (error) in
if let error = error {
print(error.localizedDescription)
return
}
self.signedIn(FIRAuth.auth()?.currentUser)
}
}
#IBAction func didRequestPasswordReset(sender: AnyObject) {
let prompt = UIAlertController.init(title: nil, message: "Email:", preferredStyle: UIAlertControllerStyle.Alert)
let okAction = UIAlertAction.init(title: "OK", style: UIAlertActionStyle.Default) { (action) in
let userInput = prompt.textFields![0].text
if (userInput!.isEmpty) {
return
}
FIRAuth.auth()?.sendPasswordResetWithEmail(userInput!) { (error) in
if let error = error {
print(error.localizedDescription)
return
}
}
}
prompt.addTextFieldWithConfigurationHandler(nil)
prompt.addAction(okAction)
presentViewController(prompt, animated: true, completion: nil);
}
func signedIn(user: FIRUser?) {
MeasurementHelper.sendLoginEvent()
AppState.sharedInstance.displayName = user?.displayName ?? user?.email
AppState.sharedInstance.photoUrl = user?.photoURL
AppState.sharedInstance.signedIn = true
NSNotificationCenter.defaultCenter().postNotificationName(Constants.NotificationKeys.SignedIn, object: nil, userInfo: nil)
performSegueWithIdentifier(Constants.Segues.SignInToFp, sender: nil)
}
}
Can someone please help? Thank you in advance.

UITextField nil on button click, but works onchange

I'm getting the following error on button click
Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value
following is the code
#IBOutlet weak var UserId: UITextField!{
didSet{
UserId.setBottomBorder()
UserId.delegate = self
}
}
#IBOutlet weak var Password: UITextField!{
didSet{
Password.setBottomBorder()
Password.delegate = self
}
}
#IBAction func logincta(_ sender: Any) {
guard let _ = UserId.text, UserId.text?.characters.count != 0 else {
print("test")
return
}
}
but works fine in the following onchange code
#IBAction func UserIdChanged(_ sender: Any) {
if UserId.text == "" {
UserId.setBottomBorder()
}
else{
UserId.setPurpleBottomBorder()
}
}
#IBAction func PasswordChanged(_ sender: Any) {
if Password.text == "" {
Password.setBottomBorder()
}
else{
Password.setPurpleBottomBorder()
}
}
i wonder how it worked in onchange event "if UserId.text == "" but not in button click
I've tried your code and it seems to work...
Anyway maybe try to use the guard in this way:
guard let numOfChars = UserId?.text?.count, numOfChars != 0 else {
print("test")
return
}

Resources