Sending mail from Firebase webapp - email

var express = require('express');
var app = express();
var nodemailer=require('nodemailer');
var transporter = nodemailer.createTransport('smtps://username#gmail.com:password#smtp.gmail.com');
app.get('/sendMail', function(req,res){
var mailOptions={
to: 'receiver#gmail.com',
subject: 'Test Mail',
html: 'Testing the Mail'
}
transporter.sendMail(mailOptions,function(err,response){
if(err){
res.end('Mail not sent');
}
else{
res.end('Mail sent');
}
});
}).listen(9091);
console.log('This is running');
I am developing a firebase web app. I need to send an email via my web app. I saw some tutorials and found some code. Using the above code I am able to send emails. It runs in the port 9091. The message will be sent when the address bar has www.mywebsite.com/sendMail. But when I host this page to Firebase what changes to be done in this code, whether there must be a change in the port number?. Please help to implement this code in my web app.

Update 2019: Alternatively, you can use the new Trigger Email Firebase Extension (currently in beta).
As I mentioned on my comment, the problem is: your web app was built with NodeJS and you're trying to host it on a static host environment (Firebase Hosting). But Firebase also has Cloud Functions - a service that let's you run functions on a NodeJS environment. So you should deploy your app to that service instead.
It's really easy to Get Started with Cloud Functions. And since you have already set up Firebase hosting, you can simply go to that directory and set up Cloud Functions by using this command:
firebase init functions
A new folder named "functions" will be created and an index.js file will be automatically added to that folder. Now that's the file where you're going to write your functions (we're actually just gonna need 1 function triggered by HTTP to send the email).
So in order to create this function, you would no longer need Express. you can remove that and then change a bit your index.js file to add firebase-functions, so it would become:
//var express = require('express'); No longer needed
//var app = express(); No longer needed
var nodemailer=require('nodemailer');
const functions = require('firebase-functions');
var transporter = nodemailer.createTransport('smtps://username#gmail.com:password#smtp.gmail.com');
exports.sendMail = functions.https.onRequest((req, res) =>{
var mailOptions={
to: 'receiver#gmail.com',
subject: 'Test Mail',
html: 'Testing the Mail'
}
transporter.sendMail(mailOptions,function(err,response){
if(err){
res.end('Mail not sent');
}
else{
res.end('Mail sent');
}
});
});
Now when you want to send a message, you can use this url: https://us-central1-<project-id>.cloudfunctions.net/sendMail
Replace <project-id> with your Firebase Project ID.

Related

How to use Firebase Cloud Firestore with Google Chrome Extension?

I want to use the Firestore database to save some input data from Google Chrome Extension (i.e., the user email). I am also using Firebase Authentication which works as expected (i.e., the user is able to login successfully). I am now trying to save the email of the user in the database. However, the code below is not working.
Here is the code (please note that I am not actually saving the email of the user and this is just testing whether the email is being saved in the database):
var firebaseConfig = {
...
databaseURL: "project.firebaseio.com",
...
}
firebase.initializeApp(firebaseConfig);
var db = firebase.database();
db.collection("users").doc("test").set({
email: "some-email#email.com"
});
Also in the .html page, I have
<script src="https://www.gstatic.com...-firestore.js"></script>
In case you need to inject Firebase Web Javascript Module version 9+ inside an webpage, here is a gist with an example:
https://gist.github.com/cheadrian/d3a6604c0f680980cd232a89a1719153
Basically you need to refer a Javascript inside "content_scripts" in manifest.json witch will add the Firebase code before close of the <body> tag.

Cannot send password request reminder using Flutter connected with Parse-server

Hello i have app written in flutter which uses data from parse server.
According to flutter doc:
/// Reset password
response = await user.requestPasswordReset();
if (response.success) {
user = response.result;
}
I'd like to send e-mail using my parser with change password link.
When i press button with that function assigned - i get information: "E-mail sent"
On flutter side i'm getting that output:
Function: ParseApiRQ.requestPasswordReset
I/flutter (28247): Status Code: 200
I/flutter (28247): Payload: {"className":"_User","email":"testazaz#gmail.com"}
On parser side i have installed something like this:
simple-parse-smtp-adapter Configured as doc says.
I don't getting any Error/Info logs from parser. Can you tell me how to configure it properly? Maybe you know other way - how to connect flutter with parser to send e-mail verification or password change e-mails.
After couple days i finally resolved this problem with help of #DaviMacêdo.
I implemented Sendgrid Adapter.
In your parse node-modules folder install this module using cmd:
npm i parse-server-sendgrid-adapter
Remember to require module at the top of the file:
var SimpleSendGridAdapter = require('parse-server-sendgrid-adapter');
var api = new ParseServer({
...,
emailAdapter: SimpleSendGridAdapter({
apiKey: 'sendgridApiKey',
fromAddress: 'fromEmailAddress',
})
});
You can get api key here
and set up sender e-mail here
I hope it helps saving much time for others facing the same problem!

Flutter oAuth : how to get started with OAuth and Stripe connect

I am trying to implement stripe connect in my flutter app. Here are the steps I need to implement. Can anyone please navigate me on how I could achieve this in Flutter?
I am able to create a button with the endpointUrl but that's all..
Thanks
I found out this myself using firebase cloud functions:
first you create an https function in the firebase cloud function
then you add the link created by the function to your stripe dashboard
then you write the following logic to your function
obtain the the authorisation code
fetch data from stripe
save the response somewhere (in my case in realtime database)
Here is the function
exports.connectStripeStandardAccount = functions.https.onRequest((req, res) => {
let authCode = req.query.code;
return stripe.oauth.token({
grant_type: 'authorization_code',
code: authCode,
}).then(async response => {
await admin.database()
.ref(`/accounts/${authCode}`)
.set(response);
return res.send("Well done, account integration is completed. You can now close the window and go back to the app");
});
});
The answer selected is not completely correct:
If you dont assign the account_id to a user then it's of no use.
The only way to pass the user_id (fUser.uid) is to pass it using the state parameter.
exports.StripePI = functions.https.onRequest(async (req, res) => {
// console.log('accountIdq ' + req.query.error);
// console.log('accountIdq ' + req.query.state);
// return;
// if(!req.query.code)
// return res.send("An Error has occured please try again");
const response = await stripe.oauth.token({
grant_type: 'authorization_code',
code: req.query.code,
}).then(async response => {
var connected_account_id = response.stripe_user_id;
await admin.firestore().collection('Registration').doc(req.query.state)
.update({customer_id : connected_account_id});
return res.send("Well done, account integration is completed. You can now close the window and go back to the app");
});
});
If you want to create an in-app stripe connect account registration with flutter you will need these:
A server or service to complete the OAuth like Firebase Functions or Integromat (I used Integromat)
A link that will redirect to your app (I used Firebase Dynamic Link)
STEPS TO CREATE THE REGISTRATION FLOW
INTEGROMAT/FIREBASE FUNCTIONS SETUP
I decided to use Integromat instead of Firebase Functions because is easier to set up, doesn't need any code, and decreases my server load.
If you want to create it on Firebase Functions you will need to have a Blaze Plan
If you don't know it, Integromat will automate processes that you currently handle manually, via webhooks. It is not only capable of connecting apps (like GoogleCloud, Facebook, AWS...) but can also transfer and transform data.
Create a new scenario and add a Custom Webhook. Click on it and click on add, name it, and save it. It will now create a custom link to your webhook.
Close and click on the semi-sphere next to the webhook, to add the new module.
Select HTTP and Make a Request.
In the URL section insert https://connect.stripe.com/oauth/token.
Method POST.
Body Type Application/x-www-form-urlencoded.
Create now those fields :
Key client_secret - value your stripe client secret You can find it on your stripe dashboard. I advise you to first use the test mode and after that, change the value to the live key.
Key grant_type - value authorization_code
Key code - leave the value blank. We will add it later.
Save and close
For Firebase Functions you can create a new HTTPS function (I didn't test this)
var stripe = require("stripe")(*your stripe client secret*);
exports.connectStripeStandardAccount = functions.https.onRequest((req, res) =>{
let authCode = req.query.code;
return stripe.oauth.token({
grant_type: 'authorization_code',
code: authCode,
});
});
Remember to install stripe package npm install stripe
STRIPE SETUP
If you are in the test mode go to this link
If you are in the live mode go to this link
Go on the bottom and activate oAuth for standard accounts or for Express Account.
Click on Add URI and add the webhook link of Integromat that you created or the link related to your Firebase function.
If you used Firebase add this link https://us-central1-<project-id>.cloudfunctions.net/connectStripeStandardAccount
For Integromat you will need to create the structure. To do this click on Test OAuth, copy the link, and open it in incognito mode. Open your Integromat scenario and click on your webhook. Now click on Re-determine data structure.
Return to your stripe registration page and click on Ignore account form at the top.
Return on Integromat and select the HTTPS request, modify the field code, and insert the variable code (will open a dialog with all queries from the webhook). Confirm and save.
Now click on the play button and reopen the stripe registration link in incognito mode and click on Ignore account form. Return in Integromat and add a JSON module after the HTTPS request. In the JSON string insert the Data variable and save. Create a Webhook Response module after the JSON module.
In the status put 301, then click on Ok.
DEEP LINK SETUP
It's time to set up the redirect link that will return the user to our flutter app or on our website if the user hasn't it installed.
I used Firebase Dynamic Link You can follow this tutorial for set up.
Go to the dashboard and create a new Link prefix and a new dynamic link, remember to select to redirect your users to the right app.
Click on the three dots in your dynamic link row and click on Link Details. Copy the extended link.
Open Integromat and select the last module you created (Webhook Response). Click on Show advanced settings and on the Header add :
Key Location - value the extended dynamic link that you copied.
If you want your app to elaborate data from the stripe OAuth response you can modify the extended dynamic link by adding ? on the link parameter: link=https://test.page.link?stripe_user_id={{14.stripe_user_id}}
And select the variable parsed from the JSON module. Remember to click on the save icon to save your scenario.
On Firebase Functions you can do this when the function stripe.oauth.token finish (I didn't test it):
res.setHeader('Location', your dynamic link);
res.status(301).send();
Remember to deploy it.
FLUTTER APP SETUP
The code here is very simple. To initialize the connect account registration you only need to set up a button that will launch the stripe connect URL. You can use launch(url);
You can find that URL here. Remember to be logged in to your stripe account to get the right stripe client id. You can easily get it in the same section you added the webhook link in your stripe connect settings.
Delete &redirect_uri=https://sub2.example.com on the URL.
Now you can test your app and will see that when you complete your stripe connect registration/login you will be redirected to your app.
If you want to have an in-app web view you can use this package
To handle the response, you need to have installed the package firebase_dynamic_links
Set your Main widget Stateful and on the initState run the method getDynamic() :
void getDynamic() {
FirebaseDynamicLinks.instance.getInitialLink().then((value) {
if (value != null) {
_connect(value);
}
});
FirebaseDynamicLinks.instance.onLink(onSuccess: (value) async {
if (value != null) {
_connect(value);
}
}, onError: (error) async {
debugPrint('DynamicLinks onError $error');
});
}
void _connect(value) {
Uri deepLink = value.link;
print("Link :" + deepLink.path);
print("Query :" + deepLink.queryParameters.toString());
String stripeUserId = deepLink.queryParameters["stripe_user_id"];
}
You need to have both of them to handle dynamic links when your app is running and when it's closed.

Restify and React : how to serve correctly as Express?

I have developped an app with create react app and i want to deploy it. React is used for the front end and Restify publish API that is consumed by the front end.
The app uses browser history and when i refresh the page Restify return JSON object saying that the route is unknown.
To solve this problem, the Create-react-app documentation explains how to do it well with the Express server :
const express = require('express');
const path = require('path');
const app = express();
app.use(express.static(path.join(__dirname, 'build')));
app.get('/*', function (req, res) {
res.sendFile(path.join(__dirname, 'build', 'index.html'));
});
Here is the doc :
https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/README.md#deployment
Use Case
As mentionned in the create-react-app doc, i use restify to serve static front end React app :
server.get(
/\/(.*)?.*/,
restify.plugins.serveStatic({
directory: "./static",
default: "index.html"
})
);
It's all right with Express but not with Restify. With Express, we must use a middleware first to server static files and next we have to redirect routes to the "index.html" front end app.
With Restify, i have just only used the serveStatic plugin, but it's not enough.
So, if you have an idea to solve that... it would be fabulous !
thx

node.js/everyauth: Maintaining session information with auth request

Ok, so I'm banging my head against the wall trying to figure this out! I'm trying to authenticate via Facebook.
I've got node (0.6.13) running express on an amazon ec2 server. I'm using everyauth for auth, and I have mongodb (mongodb native and connect-mongodb) for persistence. Here is how I instantiate mongo:
var MongoStore = require('connect-mongodb');
var mongo = require('mongodb');
var mongoServer = new mongo.Server('localhost', 27017, {auto_reconnect: true, native_parser: true})
var mongoStore = new MongoStore({
db: new mongo.Db('test', mongoServer, {})
, reapInterval: 3000
});
I'm trying to authenticate through facebook using everyauth. So let's assume my app is running on port 3000, at http://ec2ip:3000/. My facebook app settings have the Website being redirected back to http://ec2ip:3000/.
Express is setup like so:
app.get('/', function (req, res) {
if(!req.session.auth || !req.session.auth.loggedIn)
{
console.log("Not authorized!");
res.redirect('/auth/facebook/');
}
else
{
console.log("Authorized!");
res.sendfile(__dirname + '/www/index.html');
}
});
This was working locally, before I put it on the server. What will happen is that it will correctly authenticate with facebook, and redirect to my website, however req.session.auth will always be undefined, and it will redirect forever. Even though I know it's successfully authenticated, it's just not passing the right session information.
It has something to do with setting up the redirect requests properly so session information is maintained, but I don't understand how it's working under the hood.
Any advice/help would be greatly appreciated. These are the related questions/problems I'm having, but I don't know how to apply it in my case: https://github.com/bnoguchi/everyauth/issues/189 and Node.js & Express session problem
Check what is the value in "req.session". Then go get directly the value in object that you need.