Firebase Database saving data after approvement - ios

I'm using firebase database on an iOS app! I'm writing in swift. I'm using a 'Send' button to write data (ex. textField and label values) on my firebaseDatabase. Is there any way to accept or decline data on my database? What I mean is if a user add something to textfield and press send (which means adding it to my database), I want to accept or decline it to my database, before adding it there!
My button action:
#IBAction func saveBtn(_ sender: Any) {
//Saving item to database
if commentTextField.text != "" && placeLabel.text != "Location"
{
let place = placeLabel.text
let key = dbRef!.child("placeLabel").childByAutoId().key
dbRef!.child(place!+"/placeLabel").child(key).setValue(place)
dbRef!.child(place!+"/comment").child(key).setValue(commentTextField.text)
dbRef!.child(place!+"/rating").child(key).setValue(ratingControl.rating)
commentTextField.text = ""
//alert
createAlert(title: "Thank you!", message: "Review submitted.")
self.navigationController?.popViewController(animated: true)
}else{
//alert
createAlert(title: "Why don't write a review?", message: "Please write a review.")
}
}

If I have understood you currectly, then First way:
1) Add extra field like isAccepted
2) Add new value to your node, but show only if isAccepted == true.
3) If false show some UIView for approving.
Second way:
1) You should create additional node with name like Suggested
actions
2) Let user add to this node
3) Check from your user this node and accept/decline.
4) If accepted - add to final node
Hope it helps

Another way to enable offline capability of firebase database. It will enhance the processing and you don't need to handle this.This will achieve with one line of code only.

Related

iOS ShareContext tapping on Suggestion Intent property of extensionContext is nil

I have a ShareExtension in my iOS app. I am trying to use Suggestions. I can successfully 'donate' the intent using the following code from the apple developer website:
let groupName = INSpeakableString(spokenPhrase: "Juan Chavez")
let sendMessageIntent = INSendMessageIntent(recipients: nil,
content: nil,
speakableGroupName: groupName,
conversationIdentifier: "sampleConversationIdentifier",
serviceName: nil,
sender: nil)
// Add the user's avatar to the intent.
let image = INImage(named: "Juan Chavez")
sendMessageIntent.setImage(image, forParameterNamed: \.speakableGroupName)
// Donate the intent.
let interaction = INInteraction(intent: sendMessageIntent, response: nil)
interaction.donate(completion: { error in
if error != nil {
// Add error handling here.
} else {
// Do something, e.g. send the content to a contact.
}
})
This works fine and I am able to see my app icon in the suggestion row on the top for each conversation. However when I click on the suggestion, the intent property of the extentsionContext is nil:
override func viewDidLoad() {
super.viewDidLoad()
// Populate the recipient property with the metadata in case the user tapped a suggestion from the share sheet.
let intent = self.extensionContext?.intent as? INSendMessageIntent
if intent != nil { // this is nil despite selecting suggestion
let conversationIdentifier = intent!.conversationIdentifier
self.recipient = recipient(identifier: conversationIdentifier!)
}
}
My ShareExtension plist is as follows:
The other odd behaviour is that I'm able to do the donate from the main app but not from the app extension. In the main app the only relevant entry in the plist is the same NSUserActivityTypes entry. Not the NSExtension entries.
My understanding is that tapping on the suggestion, the extensionContext should contain the intent.

phone authentication using firebaseUI ios swift

i'm ios fresher. i want to retrieve phone number with country code from the default firebase phone authentication screen.
This is default screen that firebase provides. how can i retrieve country code & phone number on verify buttonClick that is enter by the user and how can i get verify buttonClick event? Is there any library provided function to get buttonClick?
i am stuck here
fileprivate func startLogin() {
self.authUI?.delegate = self
self.authStateListenerHandle = self.auth?.addStateDidChangeListener { (auth, user) in
if user != nil {
print(user)
}else {
do{
try self.auth?.signOut()
print("singning out done")
}catch{
print("Error while signing out!")
}
let phoneProvider = FUIPhoneAuth(authUI: self.authUI!)
self.authUI?.providers = [phoneProvider]
phoneProvider.signIn(withPresenting: self.rootController!, phoneNumber: nil)
}
}
}
this code open phone number login screen for me, bt after providing phone no. when i click to the verify button i have to pass user's phone no. in bellow code to send opt on users mobile, bt i don't know how can i get verify buttonClick event & how can i retrieve phone no. & country code that user input in the phone authentication screen.
PhoneAuthProvider.provider().verifyPhoneNumber(("need to pass phone number with country code here")!, uiDelegate: nil) { (verificationID, error) in
if let error = error {
// self.showMessagePrompt(error.localizedDescription)
return
}
// Sign in using the verificationID and the code sent to the user
// ...
}
Please also explain me right flow of verification.
Why dont you use the Firebase methods to access the phone number once the tocken is verified?
Access the tocken and verify the credibility and after that you can use decodedTocken.phone_number property . Use below to access the phone number
admin.auth().verifyIdToken(idToken).then(function(decodedToken) {
var uid = decodedToken.phone_number;
// ...
}).catch(function(error) {
// Handle error
});
Maybe after you access the phone number you can use the string and break down the country code, just a sugesstion, take a look at the below described answer with how to verify the phone number as well
https://stackoverflow.com/a/45227042/10021979

How to check whether the user is new user or old user

I have one login screen, which have email, password. And in register screen after user registred they will come to login screen to login.
That time I need to check , if the user is first time user or old user. If first time user means I need to redirect them to my feedback screen. Or old user means I need to redirect them to my home screen. How to do that with firebase?
Her my code for login screen :
#IBAction func loginWithUserNamePassword(){
loginWithMailAndPassword((username.text?.trimWhiteSpace)!, password: (password.text?.trimWhiteSpace)!) { (user, error) in
if error != nil{
KRProgressHUD.dismiss()
SCLAlertView().showError("Login Error", subTitle: error!.localizedDescription)
}
else {
KRProgressHUD.dismiss()
if user!.emailVerified{
currentUser = user
enableSync()
self.callHomescreen()
}
else
{
AlertView().showError("Login Error", subTitle: "This email is has not been verified yet")
}
}
}
}
Or else in my feed back screen there are some text fields. And the model class is :
var feedbackData = [files]()
class files {
// having some string variables
}
By using this, if my data is empty in my feedback screen redirect the user to feedback screen or else redirect them to home screen. Can we do that?
Updated :
if profileData.FirstName.characters.count <= 0 {
print("Home screen calling")
}
else if profileData.FirstName.characters.count > 0 {
print("feedback screen calling")
}
Thought of trying like this. But no use.
If I understand your question currectly, once user is logged in, you want to check the creation date of the use account. To do so you have two options:
The server side. If you are using Firebase database just add the date of creation. Firebase documantation does not offer a method to get the creation date on the app side.
The app side. User user defaults, when the user login in the first time set the date for that user. When you get to the login screen again, check for existance. I would reccomend using the user id as the key.
For example:
Your user just logged in, you want to check if it the first time that he did:
if let displayName = FIRAuth.auth()?.currentUser?.displayName {
//Make sure we have the user
if UserDefaults.standard.bool(forKey: displayName) {
// try to get the user default for the spacific key
let wasConnected = UserDefaults.standard.bool(forKey: displayName)
if wasConnected {
print("This user was connected")
}
} else {
// This user was never connected
// We set the default to his ID
UserDefaults.standard.set(true, forKey: displayName)
UserDefaults.standard.synchronize()
}
}
To use the date, I think the easiest way is to convert the date to string.
Fiddle with the code to do exactly what you want.

NSUserDefaults are not being saved [duplicate]

This question already has answers here:
NSUserDefaults not saving properly
(4 answers)
Closed 7 years ago.
I am having a bear of a time getting my NSUserDefaults to save when the user accepts the license. I'm guessing I am missing something simple but as I have been staring at this for two solid days now, I probably wouldn't see it if it bit me. This is my first project so please understand I am very new to this. Thank you for you patience and assistance.
In the main VC a function runs on ViewDidLoad to determine if the user has accepted the license.
override func viewDidLoad() {
super.viewDidLoad()
print("ViewController.swift View Did Load")
userLicense()
Here is that function:
func userLicense() {
if licenseStatus == nil {
print("nil status - The NSUserDefaults value for lisenceStatus is", licenseStatus)
segueIdentifier = "showEULA"
self.segue()
print("First Run or Not yet accepted or declined. License Status var = ",licenseStatus)
} else {
licenseStatus = NSUserDefaults.standardUserDefaults().objectForKey("licenseStatus")! as? String
print("userLicense func licenseStatus var is ",licenseStatus)
if licenseStatus == "Declined License" {
print("declined status - The NSUserDefaults value for lisenceStatus is", licenseStatus)
segueIdentifier = "showEULA"
segue()
print("Declined License. Send user back to EULA screen")
} else
if licenseStatus == "Accepted License" {
NSUserDefaults.standardUserDefaults().objectForKey("licenseStatus")
print("accepted status - The NSUserDefaults value for lisenceStatus is", licenseStatus,". The app should run.")
//segueIdentifier = "backToLoginScreen"
//segue()
//print("Accepted License")
}
}
}
If the user is not licensed, he is segued to the License Acceptance VC and this code runs:
There is a button to accept the license:
#IBAction func acceptEULA(sender: AnyObject) {
NSUserDefaults.standardUserDefaults().setObject("Accepted License", forKey: "licenseStatus")
licenseStatus = NSUserDefaults.standardUserDefaults().objectForKey("licenseStatus")! as! String
print("The Accepted func NSUserDefaults license Status is ", licenseStatus)
segueIdentifier = "backToLoginScreen"
self.passThroughError = "You have chosen to accept the user license. Click cancel to return, otherwise enjoy using MORE 2 Go."
self.passThroughErrorAlertController("Confirm Accept License", error: passThroughError)
}
And a button to Decline the license:
#IBAction func cancelApp(sender: AnyObject) {
NSUserDefaults.standardUserDefaults().setObject("Declined License", forKey: "licenseStatus")
licenseStatus = (NSUserDefaults.standardUserDefaults().objectForKey("licenseStatus")! as? String)!
print("The NSUserDefaults licenseStatus is ", self.licenseStatus)
segueIdentifier = "backToLoginScreen"
self.passThroughError = "You have chosen to decine the user license. Click cancel to return, otherwise click OK and the app will be inactive."
self.passThroughErrorAlertController("Confirm Decline License", error: passThroughError)
}
As you see, it is in these button IBActions that I set the licenseStatus var to the appropriate value. The print commands show in the logs that the values are set correctly but when the user is passed back to the login VC, the value has not stuck. Here is the function where the sequel is actually called, in case this is where I am missing a step:
func passThroughErrorAlertController(title:String, error:String) {
let passThroughAlert = UIAlertController(title: title, message: passThroughError, preferredStyle: UIAlertControllerStyle.Alert)
passThroughAlert.addAction((UIAlertAction(title: "Cancel", style: .Cancel, handler: nil)))
passThroughAlert.addAction((UIAlertAction(title: "OK", style: .Default, handler: {action in
print("The user clisked OK, the license status is ", self.licenseStatus)
self.performSegueWithIdentifier(self.segueIdentifier, sender: self)
//self.dismissViewControllerAnimated(true, completion: nil)
})))
self.presentViewController(passThroughAlert, animated: true, completion: nil)
}
I apologize for such a lengthy post but as I said, I have been trying to implement this for two days and none of the references I can find seem to be helping (or I am just missing the forrest for the trees now that I am so far in). Thanks again for your assistance.
You need to synchronize your NSUserDefaults after setting value to it:
NSUserDefaults.standardUserDefaults().synchronize()
or in Objective-C:
[[NSUserDefaults standardUserDefaults] synchronize];
The NSUserDefaults is a file, and settings value to it is writing data to a file - a heavy IO code, so use it only if you need to save some data between app running, and synchronize it after you insert data to it.
If you inseting more than one value, call it at the end, and it will flash all the last inserted data to the file.

Parse signup going to next view controller if fields are missing

So I am trying to create a signup page, and I am running into some trouble. I want the user to HAVE to fill in all the information before they hit signup. After they hit the signup button, if they do not have all of the fields filled in they get an UIAlertView error for many different things. When I hit signup, it takes the user to the next page and then displays the UIAlertView, I do not want this to happen. I can't figure out what is happening. If the UIAlertView comes up if they do not have a username or email filled in I need the UIAlertView to display after they click the button and not go to the next page. I have a performSegue method in my code but it is performing first, and not last. Can anybody help me? I will include the screenshot of my storyboard as well.
user.signUpInBackgroundWithBlock {
(succeeded: Bool, error: NSError?) -> Void in
if let error = error {
let errorString = error.userInfo?["error"] as? NSString
if fullname.isEmpty || email.isEmpty || username.isEmpty || password.isEmpty {
var emptyFields:UIAlertView = UIAlertView(title: "Plese try again", message: "It looks like you forgot to fill out all the fields. Please make sure all the fields are filled out so we can create an account for you.", delegate: self, cancelButtonTitle: "Try again")
emptyFields.show()
} else if error.code == 203 {
var takenEmail:UIAlertView = UIAlertView(title: "Please try again", message: "It looks like that email has already been taken, please try again.", delegate: self, cancelButtonTitle: "Try again")
} else if error.code == 202 {
var usernameTaken:UIAlertView = UIAlertView(title: "Please try again", message: "It looks like that username is already in use, please try again.", delegate: self, cancelButtonTitle: "Try again")
}
}
}
There are a few ways to do this. The way I would do it is as follows.
Step 1.
Ok you want to select your Sign Up View Controller.
Step 2.
You are going to control click and drag from the Yellow View Controller Icon to the Second View Controller. In the Menu that appears choose the Show Or Present Modally Option.
Step 3.
Choose the Segue you just created and change its Identifier, In the right side panel to "signupSuccessful".
Step 4.
You can set the code up like this.
if usernameTF.text.isEmpty || passwordTF.text.isEmpty {
var emptyFields = UIAlertView()
emptyFields.title = "Plese try again"
emptyFields.message = "It looks like you forgot to fill out all the fields. Please make sure all the fields are filled out so we can create an account for you."
emptyFields.addButtonWithTitle("Try Again!")
emptyFields.show()
}else if usernameTF.text == "ERROR CODE 203" {
//do same thing with the alert view!
}else if usernameTF.text == "ERROR CODE 202" {
//Do another alert view here
//You can keep adding the "else ifs" for any other error codes
}
//Here is where it will send to the second view when everything above is false!
else {
//Here we present the second view.
self.performSegueWithIdentifier("signupSuccessful", sender: self)
}
There you go.
Here is a download of the project if you need to see the segue again, or any of the above code.
https://github.com/bobm77/ParseSegueExample
Implement the method func shouldPerformSegueWithIdentifier(identifier: String?, sender: AnyObject?) -> Bool in your view controller and return false if you don't want the segue to happen.

Resources