How to send sms messages from a React Native App programmatically ? - reactjs

I want to be able to sent sms messages though my React Native app programatically in the background.
I know how to sent sms normally in the code, but the app keeps opening the default sms app, and that is not what i want.
The user should not push any buttons to sent the sms, because my goal is to notify a phonenumber every time the user is doing a particularly task in the app.
I have tried looking at Twilio, but they dont provide a api for React Native.
Does anybody know something about how I can do this ?

With the answer from kdenz, I followed a tutorial here: Seeting up a firebase function
This is my code for sending a request to Twilio, when the firebase database value 'visible' is changing.
import * as functions from 'firebase-functions';
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
const twilio = require('twilio');
const accountSid = functions.config().twilio.sid;
const authToken = functions.config().twilio.token;
console.log(`Twilio account: ${accountSid}`);
const client = new twilio(accountSid, authToken);
const twilioNumber = 'xxx-xxx-xxx';
exports.textStatus = functions.database
.ref('/users/{userId}/data/visible')
.onUpdate(event => {
return admin.database()
.ref(`users/{userId}/data/`)
.once('value')
.then(snapshot => snapshot.val())
.then(user=> {
console.log(user[0]);
const longitude = user.longi;
const latitude = user.lati;
const phoneNumber = user.phone;
const textMessage = {
body: `See user position at Google: http://www.google.com/maps/place/${latitude},${longitude}`,
to: phoneNumber,
from: twilioNumber
}
return client.messages.create(textMessage);
})
.then(message => console.log(message.sid, 'success'))
.catch(err => console.log(err));
});

I think this is only possible with Android, as seen in this deprecated package https://www.npmjs.com/package/react-native-send-sms
For iOS, I don't think so, as seen in How to programmatically send a text message after the user has given permission?
To achieve what you want, you'll need a SMS service like Twilio. Then you can set up a server (Or a cloud function for minimal cost + easy maintainability) which receives API calls from your RN app, and sends the message to the desired recipient. You can then set up some security measures too, to prevent hackers from spamming the API.
Or if you don't care about security (Which I highly don't recommend), you can directly call Twilio send message API within your app, which is dangerous because hackers can easily extract your Twilio authorization token and use it to send messages for themselves.

On android, it is possible to send sms from user's number programmatically without user interaction.
But on IOS, the only way you can send an SMS without user interaction is to use an external provider such as Twilio; but the message will come from your server's number, not from the user.
I have already answered for same kind of question. Check this out
Is there anyway to send sms in background for both Android & IOS?

Related

Bypassing Firestore Security Rules in jest tests

Currently working on a React/Typescript/Firebase Firestore project. When writing Jest-tests for some actions/functions that are called from the UI, I ran into the following problem:
In the test file I'm able to setup the firestore client using the v9 api and make it talk to emulator
const app = initializeApp(config.firebase);
const firestore = getFirestore(app);
connectFirestoreEmulator(firestore, "localhost", 8080);
In addition I also found out how to setup the admin client and make it talk to emulator
process.env.FIRESTORE_EMULATOR_HOST = "localhost:8080";
const serviceAccount = require("../../../my-key.json");
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
...config.firebase
});
The test itself looks something like this:
describe("createCompanyAndRating action", () => {
test("call createCompanyAndRating and make sure it creates a proper rating entity", async () => {
// omitted: set testRatingFormState and other test data that are passed as args and
// pass in the firestore db client
const {
ratingId,
companyId,
} = await createCompanyAndRating({
ratingFormState: testRatingFormState,
visitorId: testVisitorId,
firestore,
});
// verify result by fetching the rating entity from the emulator db using the admin client
const ratingPath = `companies/${companyId}/ratings/${ratingId}`;
const ratingSnap = await admin.firestore().doc(ratingPath).withConverter(ratingConverter).get();
const rating: Rating | undefined = ratingSnap.data();
// omitted: verify result with some Jest expect-statetments...
});
})
My problem is now that the Firestore security rules apply and only authenticated users can write docs in the collections used in the createCompanyAndRating function, so the test already throws an error when calling that function.
In this scenario I'm not interested in testing the security rules per se.
Is there a way to bypass the security rules for the test?
If yes, how do I have to setup the firestore client?
Is there even the possibility to somehow impersonate a user in the test?
In addition, please note that I can't to pass the admin client into the createCompanyAndRating function as the admin client API is different from the v9 firebase API that I'm relying on in the createCompanyAndRating function implementation (tried and it didn't work and not only because some type errors in the way).
Maybe my whole approach is a little misguided and I should rather concentrate on testing the internals of the createCompanyAndRating function where I do a lot of factory stuff that could be tested without db interaction.
Anyway, any help/guidance is much appreciated.
Thanks for confirming that I was looking in the right place (i.e. #firebase/rules-unit-testing). Finally figured out what the problem was, missed an "await" in createCompanyAndRating, so the firestore admin instance wasn't getting the data (and I though it was a admin config issue...) Thanks!

Can we store data coming in console to our database?

I am working with angular,Mongodb,Nodejs,express. simply a Mean stack.
my website is related to shopping where the carts loads dynamically. the products added to cart should be sent as mail to owner.
can we send directly mail? is yes please explain the process how.
if not should be stored in database then how?
So, the question is very unclear here. But I'll try my best to explain all the situations. So that, you don't have to mess with it a lot. I'll explain how you can send a mail to the user using front-end only or using your server.
To send an email to a user, we need to do it on the backend. That means you'll have to write some code in your server for sending the email to your client. As you have a MEAN Stack application, you must be familiar with Node package manager.
npm has a package called nodemailer that can be used for sending emails to the users. But make sure you write those emails in a good manner so that they don't end up in the spam box.
You can install nodemailer using
npm install nodemailer
Here's a sample code from w3schools
var nodemailer = require('nodemailer');
var transporter = nodemailer.createTransport({
service: 'gmail',
auth: {
user: 'youremail#gmail.com',
pass: 'yourpassword'
}
});
var mailOptions = {
from: 'youremail#gmail.com',
to: 'myfriend#yahoo.com',
subject: 'Sending Email using Node.js',
text: 'That was easy!'
};
transporter.sendMail(mailOptions, function(error, info){
if (error) {
console.log(error);
} else {
console.log('Email sent: ' + info.response);
}
});
You may also find other and maybe even better alternatives with a simple google search.
Also, i don't think there's any point in storing this data in the database unless you need it for future use. I don't know the flow of your ecommerce application. So, I'll leave this decision for you to take.
And if you want to send the e-mail directly from the front-end, there's a workaround. Sending emails requires a server, but you can use someone's else backend server for this. Basically a BaaS(Backend as a Service). You can check this previously answered question on stackoverflow for more information regarding sending emails directly from the frontend of an application.
How can i send emails without a server ? Only front-end Javascript

"mock app" how to search through a database for matches? (react-native app)

Im working on a mock app as a project to have for my portfolio as a frontend developer.
So far i've been able to fairly accurately mock some posts requests in my app ( requests for fetching data, logging in, etc ) here is an example of my login func
export const loginUser = async ({
username,
password,
onSuccess = () => {},
onFailure = () => {},
}) =>
postReq({
endpoint: LOGIN_USER,
body: {
username,
password,
},
onSuccess,
onFailure,
});
all of my "Data" lives in a json file in my project file.
however not very familiar with the backend side of things, How would the backend normally perform a search that returns data ? and whats the closest thing i can do from the frontend? I've only recently discovered regular expression functions, is this a path in the right direction? Thank you very much, Im excited to keep learning.
I think you are using redux or useReducer kind of logic to handle your login. This seems fairly true what you did for authenticate user from frontend side.
For backend side;
1- You send your request(via axios, fetch, ajax etc) to your server(backend) like this and waiting for a response.
2- You are taking this information from your request body as you send this informations in your request body which is the preferred way.
3- You check for username in your database if there is a collasion, you will check for password correctness which i advice you to store your passwords hashed and check correctness via hash compare.
4-If there is no collasion or password is not correct you send an error with relative status code like 500 and a message "A user with
the given username and password could not be found"
5- If password is true, you send your feedback your frontend with a success status response(like 200).
6- You taking your response from your server and take the necessary actions accordingly
And keep up your passion you will have a lot of fun

Sending notification automatically firebase

I have an application that sends data to the firebase realtime database. Now I'm creating a dashboard to manage this data. At the moment I need to receive a notification on the dashboard when the user sends some new data to the firebase. I need to receive a message with the data id he sent and submit a notification similar to a social network.
I'm using FCM, I've already configured and tried to implement the onCreate () function. But when the bank is upgrading, this function is not being performed.
I'm implementing the code in the dashboard
const functions = require("firebase-functions");
const admin = require("firebase-admin");
admin.initializeApp();
exports.makeUppercase = functions.database
.ref("users")
.onCreate((snapshot, context) => {
const original = snapshot.val();
console.log(original);
});
I'm actually lost on how to do this, I read the documentation, but I didn't quite understand the correct steps to follow. Is there anything I should do before that? Or is this method of doing wrong?

Magic Link Authentication in react SPA

For a small app catering to a very small set of users, we are planning to implement magic link authentication. The user would come to the application, enter their email address, get a magic link on the email address, after the user clicks on the link, they are logged in to the app.
I am not able to find enough resources to figure out how to do it in a SPA. Here are some helpful links:
Magic Link with Node
https://medium.com/#aleksandrasays/sending-magic-links-with-nodejs-765a8686996
https://medium.com/one-more-thing-studio/how-to-make-magic-links-with-node-1d164c036e29
Magic Link with Auth0
https://auth0.com/passwordless
This is the SPA workflow that I have in mind:
User comes to the SPA
The SPA takes the user to the login page where they can provide their email address.
The SPA sends the email address to the backend api
The api decides whether or not the user is registered, and sends them an email with a short lived jwt.
Clicking on this link takes user to a SPA route with the jwt in query params.
The Frontend forwards this jwt to the api backend, and the api backend verifies the jwt and sets a cookie
This cookie can then be used to maintain the user session.
I want to verify this workflow, but I am not able to find enough resources.
Specifically, I want to clarify whether the magic link should send the user to the SPA and the SPA should be responsible for extracting the jwt and sending it to the API backend, or is there another way to do it?
Is this how this should be implemented? What are the security implications?
I am using react and react-router.
Cotter co-founder here.
We have a super easy magic link integration for React. Here's a guide to set up a Simple Magic Link Login for your React App.
You can integrate magic link login in 2 steps:
1. Add dependencies
yarn add cotter
2. Show the log in form
(step 2-4 in your flow)
import React, { useEffect } from "react";
import Cotter from "cotter"; // 1️⃣ Import Cotter
function App() {
useEffect(() => {
// 2️⃣ Initialize and show the form
var cotter = new Cotter(API_KEY_ID); // 👈 Specify your API KEY ID here
cotter
.signInWithLink() // use Magic link
.showEmailForm() // show email login form
.then(resp => console.log(resp))
.catch(err => console.log(err));
}, []);
return (
// 3️⃣ Put a <div> with id "cotter-form-container"
// that will contain the form
<div id="cotter-form-container" style={{ width: 300, height: 300 }} />
);
}
export default App;
You can create your API_KEY_ID here.
Done! Now you should have an email Login Form that sends a magic link to your users. Here's a working example.
The response
After the user click the link (step 5), you'll receive the following response in then((resp) => console.log(resp)):
{
"email": "youremail#gmail.com",
"oauth_token": {
"access_token": "eyJhbGciONiIsImtiJFUzI1pZCI6...",
// you'll also get a refresh token and an id token
},
"user": {
"ID": "abcdefgh-1234-5678-1234-f17786ed499e", // Cotter's User ID
// More user information
}
}
You can then send this response to your backend server and do the following steps: (step 6-7 in your flow)
Verify if the access_token (a JWT token) is valid.
If it's valid, you can register the user if the email is not recognized (you should also associate the email with Cotter's user id).
You can use the access_token for all your API endpoints, or you can generate your own session and set a cookie
Checkout this Reack Hook use-magic-link to integration Magic Link very quickly into a React app.
Read this article for more info: Simple Auth Setup for Your React App
This is the workflow for magic link:
When a user enters the email address, Magic sends verification link to the email address to verify that email. When you click on "Confirm your email", a modal will show up to log in to the app. When the user click on the "Log in to app", Public+Private keys are generated and stored on the browser. That means users own their own identity. This key pair is in embedded iframe and inaccessible to the developer in order to protect the user's private key.
Since those keys are generated on the user's client instead of magic servers, Magic will not be able to see those secrets.
Magic sdk will use that private key to generate auth token. This auth token is called DID token (Decentralized Identifier). When you decode this token, you can see the user's email address and when it was issued. Essentially, DID token is your digital signature. If we store this token in our database and if our database gets hacked, malicious users will not be able to access our private key. Then we pass this DID token to the server to check the user
Magic stores the user's email and id in indexedDb. It also stores some cookies for itself, to function properly
to work with magic, you use magic-sdk. You set the magic client ✨
import { Magic } from "magic-sdk";
const createMagic = () => {
return (
new Magic(process.env.API_KEY)
);
};
export const magic = createMagic();
then using this client:
// you have input and captured the email
if (email) {
try {
// this store public/private key on browser and returns the DID token
const didToken = await magic.auth.loginWithMagicLink({
email,
});
if (didToken) {
// once you have the token, using metadata, you can add another propertis
// iat, exp, roles etc
// then sign this with jwt
// store the token in browser
}

Resources