Shopping cart saved in firebase - order processing - xcode

my next question is about Firebase.
I have an application with spare parts for a car. In the application, a user authorized by email and password adds spare parts to his cart, which is stored in Firebase.
Question: how, by clicking the "submit order" button, send the contents of the cart to the seller (me) by mail?
Perhaps Firebase already has a ready-made solution / service for a similar task?
Does Apple's policy allow you to send the user's email address that was provided during registration for order feedback along with the request?
Here i trying to send order by MFMailComposeViewController
#IBAction func sendRequestButtonTapped(_ sender: UIButton) {
// Modify following variables with your text / recipient
let recipientEmail = "MyMail#gmail.com"
let subject = "description"
var body = "some array with ordered spare parts"
for i in objectsList {
body.append(i.objectFromPartsCatalogueListCode! + " " + i.objectFromPartsCatalogueListName!+"\n")
}
// Show default mail composer
if MFMailComposeViewController.canSendMail() {
let mail = MFMailComposeViewController()
mail.mailComposeDelegate = self //!!!
mail.delegate = self //!!!
mail.setToRecipients([recipientEmail])
mail.setSubject(subject)
mail.setMessageBody(body, isHTML: false)
mail.modalPresentationStyle = .fullScreen
self.present(mail, animated: true)
// Show third party email composer if default Mail app is not present
} else if let emailUrl = SendEmailManager.createEmailUrl(to: recipientEmail, subject: subject, body: body) {
UIApplication.shared.open(emailUrl)
}
It is difficult and opens an additional menu for choosing the method of sending. I want to receive an order with content from the application on my mail, one click by the user of the "sendRequest" button.

You can easily send emails from your app via a secure backend environment (eg. cloud functions).
There are many possible solutions, but here is one of them:
When a user hits submit, you can create a new document in a special Firestore collection (eg. emails) and have a cloud function listening to changes in that collection using a background trigger Firestore event triggers. This function will get the document changes, retrieve its data (email information, and any other metadata you've specified), and send an email using whichever email API you decide to use (eg SendGrid).
Alternatively, you can use the Firebase email extension Extension, but writing your own function isn't difficult.
An added benefit is you can store your personal email in your secure backend environment so your users won't be able to access it on their devices.

Related

AWS Cognito SignUP with custom Attributes in node js causing error

I am trying to build Signup through a lambda function with AWS user pool where I added a custom attribute called type.
When I am sending a type value with signup, an error "A client attempted to write unauthorized attribute" is populating.
I am using 'amazon-cognito-identity-js' package to save data.
Here is my code snippet
const attributeList = [];
attributeList.push(new AmazonCognitoIdentity.CognitoUserAttribute({Name:"name",Value:user.username}));
attributeList.push(new AmazonCognitoIdentity.CognitoUserAttribute({Name:"custom:type",Value:'asd'}));
attributeList.push(new AmazonCognitoIdentity.CognitoUserAttribute({Name:"gender",Value:user.gender}));
attributeList.push(new AmazonCognitoIdentity.CognitoUserAttribute({Name:"email",Value:user.email}));
userPool.signUp(user.email, user.password, attributeList, null, function(err, result){
if (err) {
return reject(err);
}
return resolve(result);
});**strong text**
After that you added a new attribute, you should select the user attributes this app client can read and write.
Steps:
Go to your Cognito User Pool page
Click on the "App Client" from the left side menu
Click on the "Set attribute read and write permissions"
Make sure you added the necessary(read/write) permissions for the needed attribute
In addition to the above answer, sometimes custom attributes may take time to reflect under clients. Because I noticed it around 15 mins but after 1 hour it was there.

How do I allow a 3rd party (twilio) access to current user account in laravel

I am making an application using laravel and twilio that gets feedback about student performance. The logic as follows.
A user, in my case the Student(called resident) logs in and uses a
web page form to send an eval request to a teacher (called
attending). This step starts a session and saves teacher info and
student info.
A random question is picked from a database and saved to the session.
The phone number of the teacher is pulled from a database and the random question is pulled from session and sent to the teacher on SMS using twilio.
The teacher responds with yes, no, or DNS (did not see) via Twilio SMS.
The teacher's response along with the student name, the teacher name and the question asked are saved to a database.
My application works up until step 5. The problem is that a new session is being started when the teacher responds via SMS. So everything after the response is saved to a new session. I can't get access to the original session. I think I need a way to automatically grant the teacher access to the student(ie. user's account). This seems to be a problem with it being a 3rd party application. Can this be done or is there another way to accomplish this?
Below is the code I am using for the response. It is not able to access the session that contains the residentName, the firstQuestion, or the attending_name data. It puts null for those values and uploads null to the database. How do I get access to the initial session in this situation?
namespace App\Http\Controllers;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Http\Request;
use Session;
use Twilio\Rest\Client;
use Twilio\Twiml;
use App\Question;
use App\Answer;
class AskFirstQuestionsController extends Controller
{
public function qOneResponse(Request $request) {
$responderNumber = $request->input('From');
session()->put('responderNumber', $responderNumber);
session()->save();
$responderAnswer = strtolower($request->input('Body'));
$residentName = session::get('residentName');
$firstQuestion = session::get('first_question');
$attending_name = session::get('attending_name');
if (strpos($responderAnswer, 'yes') !== false) {
$answer = new
Answer(['attending'=>$attending_name,'resident_name'=>$residentName,'question_body'
=>$firstQuestion, 'answer_yes'=>1]);
$answer->save();
$smsResponse = "Great! Please help us reinforce this action by providing specific feedback
to the resident about what they did. Thank You for teaching!";
} else if (strpos($responderAnswer, 'no') !== false) {
$answer = new
answer::create(['attending'=>$attending_name,'resident_name'=>$resident_name,'question_body'
=>$firstQuestion, 'answer_no'=>1]);
$answer->save();
$smsResponse = "Ugh, ok...we will work on this. If you feel comfortable, please help us by
providing specific feedback to the resident about what they need to work on. Thank You for
teaching!";
} else if (strpos($responderAnswer, 'dns') !== false) {
$answer = new
answer::create(['attending'=>$attending_name,'resident_name'=>$resident_name,'question_body'
=>$firstQuestion, 'answer_dns'=>1]);
$answer->save();
$smsResponse = "How about trying a different question?";
} else {
$smsResponse = 'Please answer yes, no or dns.';
}
return response($this->respond($smsResponse))->header('Content-Type', 'application/xml');
}
public function respond($smsResponse) {
//get responderNumber and use it below
$responderNumber = session::get('responderNumber');
$response = new Twiml();
$response->message($smsResponse, ['to' => $responderNumber]);
return $response;
}
Do I need to do some type of multiauth approach and somehow grant the teacher automatic access to the student's account (user account)? Or do I have to re-write the logic so that the response-request lifecycle closes and then try to write to the database (maybe it will then use the original session data?)? Or is there a simpler way? Please help. I have been stuck for more than a week.
Twilio developer evangelist here.
I'm not a Laravel developer, but session objects in web application frameworks like this are normally tied to a cookie that either stores the contents of the session or an ID for the session which points to the contents in a database in order to add state to a user's session within a browser.
When Twilio receives an incoming SMS message the webhook that is sent to your server is not connected to the browser session that the user is part of, so you cannot access the same data.
Instead of using the session, you should store this as part of your actual database so that you can look up the details from the database when you receive the SMS.

Migrating User to Cognito on Sign In

I am trying to migrate users to Cognito when they sign in the first time. For this I wrote a lambda function that does call an API to check if the users exist in db or not ? if the user exists, it will be created in cognito but I am not sure how do I tell the application that user is created and it should allow the user to login .
Here is the code in c#:
public async Task<Stream> FunctionHandlerAsync(Stream stream, ILambdaContext context)
{
RootObject rootObj = DeserializeStream(stream);
User user = new User(rootObj.userName, rootObj.request.password);
ApiResponse apiResponse = await MobileAuthenticateAsync(user.UserName, user.Password);
// Considering apiResponse returns "user authenticated", we create the user in //cognito. This is working.
// How do I send response back to Application so it knows that user is // //created and authenticated and should be allowed to login.
//Before returning stream, I am setting following 2 status.
rootObj.response.finalUserStatus = "CONFIRMED"; // is this correct ?
rootObj.response.messageAction = "SUPPRESS";
return SerializeToStream(rootObj);;
}
You're pretty close.
You can see the full documentation on the Migrate User Lambda Trigger page, however in short you need your response to look like:
{
response: {
userAttributes: {
email: 'user#example.com',
email_verified: true,
custom:myAttribute: 123,
},
finalUserStatus: 'CONFIRMED',
messageAction: 'SUPPRESS',
forceAliasCreation: false,
}
}
Where:
userAttribute: this is a dictionary/map of the user's attributes keys in cognito (note that any custom attributes need to be prefixed with custom:), to the values from the system you're migrating from. You do not need to provide all of these, although if you're using an email alias you may want to set email_verified: true to prevent the user having to re-verify their e-mail address.
finalUserStatus: if you set this to CONFIRMED then the user will not have to re-confirm their email address/phone number, which is probably a sensible default. If you are concerned that the password is given as plain-text to cognito this first-time, you can instead use RESET_REQUIRED to force them to change their password on first sign-in.
messageAction: should probably be SUPPRESS unless you want to send them a welcome email on migration.
forceAliasCreation: is important only if you're using email aliases, as it stops users who manage to sign-up into cognito being replaced on migration.
If you respond with this (keeping the rest of the original rootObj is convenient but not required then the user will migrated with attributes as specified.
If you throw (or fail to respond with the correct event shape) then the migration lambda fails and the user is told that they couldn't migrated. For example, because they do not exist in your old user database, or they haven't provided the right credentials.

Sent Mail checking if it is delivered and open to recipient in Laravel

I want help in scaffolding code with Laravel default Mail package to send an email to the recipient with an enhancement that checks the status either mail is delivered to recipient and then check that either recipient opened the mail or not and then change the status of that email in my db_email_list. I googled it that to add headers just like follow the example but could not get it how to get the status
$message->getHeaders()->addTextHeader('X-Confirm-Reading-To','recipient_mail');
$sendEmail->getHeaders()->addTextHeader('Disposition-Notification-To','recipient_mail');
$sendEmail->getHeaders()->addTextHeader('Return-Receipt-To','recipient_mail');
When the user has gotten the email: Simply use this piece of code:
if (count(Mail::failures())) {
return false;
} else {
return true;
}
true=delivered, false=not delivered
When user reads the email: Hm sounds like you need to include a trick in your email in order to know if user has opened/read the email by simply adding for instance including an image on your email with a route defined in your end and passing user id as query param.
<img src="http://www.example.com/user-read-email?user_id=20" />
So whenever the user opens the email img src will fire a call to your url and simmply get the user id from the url, and set the flag for that user in db.

recaptcha server side integration

i'm trying to add recaptcha to an existing contact form.
i have done step 1 (client side integration) on google
but i don't understand step2
the directions for server side say:
send a POST request with these parameters:
URL: https://www.google.com/recaptcha/api/siteverify
secret (required) 6LfWAFAUAAAAALhRhjHZ1OdoMexS50EqSuxoF5jq
response (required) The value of 'g-recaptcha-response'.
remoteip The end user's ip address.
i have my own secret key but how do i "send a POST"?
if anyone has the patience to explain this whole step, i'd greatly appreciate it.
When user deals with re-captcha, re-captcha response is appended into the relevant div by google code. You wouldn't need to worry about it.
What you need to do is to ensure if it is there and valid.
For my case, I use jqBootstrapValidation to help validating my form components.
$("#myElement").jqBootstrapValidation({
preventSubmit: true,
submitError: function($form, event, errors) {
// do something useful for error case
},
submitSuccess: function($form, event) {
event.preventDefault(); // prevent default submit behaviour
// get values from FORM
var name = $("input#name").val();
// ...
var g_captcha_response = $("#g-recaptcha-response").val();
// if response does not exist, do NOT proceed
if (!(g_captcha_response && g_captcha_response.length>0)){
return;
}
// User is HUMAN. So charge ahead.!
...
EDIT
I use recaptcha-V2 for my site.

Resources