Deep linking with Brnach.IO with sendGrid integration issue as passing params is undefined while opening link from mail using React native - react-native

Goal
I am sending email with deep linking implementation with Branch.IO with sendGrid integration. While user click on link my react native app open in phone and redirect me to screen based on query params in url which i have provided during create link in API.
Problem
I am able to open app from link but query params i have provide in link is display as blank. so i am not able to open screen where i want to redirect to user in app.
branch.subscribe(({ params, error, uri }) => {
if (error) {
console.log('Error from Branch: ' + error)
return
}
console.log("params :: ", params);
if(params.reset) {
// Redirect user to reset password screen
console.log("params.reset :: " + params.reset);
Actions.resetpassword({resetToken: params.reset});
} else if(params.verify) {
// Verify signup user
axios.post('http://localhost:3030/authmanagement', {
"action":"verifySignupLong",
"value": params.verify
}).then(response => {
Actions.login({isVerifySuccess: true});
}, error => {
Actions.login();
});
}
});
I have write this code as suggest Branch.IO documentation. In params i have send reset and verify token which i got as blank string.
Information
This code is working without integration with sendGrid in deep linking. But for mailing tracking i used sendGrid. So when i try to email with sendGrid it will create problem.
I have setup Link Branding in SendGrid account and also add CNAME in my domain as given in instruction of sendGrid integration for deep linking.
I have check mailed link in Redirect Detective portal
I have verified link and it will generate valid url with params. please look into below image for more clarification

Jackie from Branch here.
Based on your redirect link, there seems to be an issue with the SendGrid integration. Could you make sure your integration is properly set up by following the instructions here?
For some context, this is what a link should look like within your email template: http://example.com/?foo=bar
When a user clicks your link in the email, Branch processes the link and converts it to something like this:
https://vza3.app.link/3p?%243p=e_xx&%24original_url=http%3A%2F%2Fexample.com%2F%3Ffoo%3Dbar
(Where vza3.app.link is your Branch domain.)
Also, in order for SendGrid to know that the email link should deep-link and open the app, add universal="true" to the HTML, like so:
Link to your app!
If you continue to experience issues with passing deep link data via SendGrid email tracking, please reach out to us directly at integrations#branch.io with your Branch key and the link(s) you're using.

Related

Firebase Magic Link not complete in Android App

I have a React Native Project using Expo Managed Workflow.
The App is built as a expo-dev-client.
I use Firebase Native SDK to authenticate via sendSignInLinkToEmail()
I managed to request the magic link for login. It arrives and when I click it on my android device, the App comes to focus and I am even able to listen to the dynamic link when it comes in.
Problem is it does not validate with isSignInWithEmailLink() because the link I get is only the continueURL parameter of the original link in the Email.
I really don't know where the link is being cut off but I need the complete link from the Email to use signInWithEmailLink() which obviously doesn't work.
When I manually insert the link from the email into signInWithEmailLink() everything works as expected.
I really hope someone has experienced this issue and can help me out!
My Bad. Apparently I was using a Dynamic Link from firebase as I did not have action codes set correct as in:
const actionCodeSettings = {
// URL you want to redirect back to. The domain (www.example.com) for this
// URL must be in the authorized domains list in the Firebase Console.
url: 'https://www.example.com/finishSignUp?cartId=1234',
// This must be true.
handleCodeInApp: true,
iOS: {
bundleId: 'com.example.ios'
},
android: {
packageName: 'com.example.android',
installApp: true,
minimumVersion: '12'
},
dynamicLinkDomain: 'example.page.link'
};

Firebase functions auth.generateEmailVerificationLink() generating link with wrong apiKey

I have a Firebase functions project with dev and prod versions. There I'm using auth.generateEmailVerificationLink() to send email verification for a newly created user. Everything works well except in prod environment (testing locally or hosted) the apiKey in the link generated by auth.generateEmailVerificationLink() is not same as Firebase's default apiKey. And clicking that link I get the page with error code:
Try verifying your email again
Your request to verify your email has expired or the link has already been used
Note that when I get the link with the wrong apiKey, if I change it to the right apiKey. the verification works. So it seems the whole problem is related to the wrong apiKey in generated email verification link.
Also to note that the wrong apiKey is not random key but used in project front end for Google Maps apis.
The code itself is simple. (I'm leaving out code which creates user etc as those parts all work perfectly)
-Initializing Admin SDK:
import { initializeApp } from 'firebase-admin/app';
import { getAuth } from 'firebase-admin/auth';
initializeApp();
const auth = getAuth();
export { auth };
-Generating email verification email
const sendEmail = async () => {
const actionCodeSettings = {
// This url is working correctly, it is the same as in Firebase console
// and when changing the wrong apiKey to correct redirecting works correctly
url: process.env.DOMAIN as string,
};
await auth
.generateEmailVerificationLink(email, actionCodeSettings) // email is the email of newly created user
.then((link) => {
// generate email message with link
// generate mailOptions
// use transporter to send email
});
};
Thank you for any help
EDIT
I tested deleting that "wrong" apiKey from GCP credentials page and replaced it with another. Then running the function locally everything worked normally but the "wrong" is still in the verification email link even tho it doesn't exist anymore.
Firebase strongly recommends that if Admin SDK is used in Cloud Functions, among others, initializing the app should be done without parameters.
https://firebase.google.com/docs/admin/setup#initialize-without-parameters
For me it seems something is for some reason pulling that "wrong" and now even deleted apiKey from somewhere to usage.
I solved this by noticing that, unlike in dev project, Web Api Key (Project Settings>General) is different than Web App's firebaseConfig apiKey.
So I added correct permission to this Web Api Key (Identity Toolkit API is required for email verification email) found in GCP credentials and now the cloud function sends email verification emails with correct and working apiKey.

How to retrieve Stripe's Connect authorization code in react-native

I'm trying to setup oAuth for Stripe's Connect (Standard). In their setup documentation they say:
Step 1: Create the OAuth link To get started with your integration,
Your client_id, a unique identifier for your platform, generated by Stripe
Your redirect_uri, a page on your website to which the user is
redirected after connecting their account (or failing to, should that
be the case), set by you
Step 3: User is redirected back to your site After the user connects
their existing or newly created account to your platform, they are
redirected back to your site, to the URL established as your
platform’s redirect_uri. For successful connections, we’ll pass along
in the URL: The scope granted The state value, if provided An
authorization code. The authorization code is short-lived, and can be
used only once, in the POST request described in the next step.
The way I've implemented this is by sending the user to a React-Native WebView, and because this is a mobile application, a redirect_uri is not an option.
The problem is, I cant simply make a POST request to a url. there are user actions that must be taken inside of stripe, and ultimately stripe sends an authorization code to a redirect url.
So How can I obtain the authorization code that stripe doles out inside the WebView authorization process so I can finish the Stripe Connect user creation process?
You can use onLoadStart for WebView. Just check if the url from the synthetic event is what you specified in your stripe settings and handle accordingly.
onLoadStart={(syntheticEvent) => {
const { nativeEvent } = syntheticEvent;
if(nativeEvent.url.startsWith("YOUR_REDIRECT_URL"){
// your logic here
}
}}
Follow the steps
step 1 : login in mediator strip account, now open new tab and paste below url in new window and replace client id "ca_****" with the account which you want to connect with mediator account ( client id ), and hit the url
https://connect.stripe.com/oauth/v2/authorize?response_type=code&client_id=ca_************************&scope=read_write
step 2 : now press connect button and find the code from new url like
https://connect.stripe.com/connect/default/oauth/test?scope=read_write&code=**ac_**************************

How do I get react-native-inappbrowser-reborn to trigger success upon successful Facebook login

I'm trying to setup a manual flow for Facebook login, as per the docs at: https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow/
I've got my test Facebook app working as expected, i.e., I can login using a private web browser window fine. The URL I'm using is:
https://facebook.com/v3.3/dialog/oauth?client_id=<app_id>&display=popup&response_type=token&redirect_uri=https://www.facebook.com/connect/login_success.html
Now within my React-Native app, I'm using react-native-inappbrowser-reborn to present a SFAuthenticationSession on iOS. As per their docs (at https://www.npmjs.com/package/react-native-inappbrowser-reborn), I'm doing the following:
const redirectUri = "https://www.facebook.com/connect/login_success.html"
const url = "https://facebook.com/v3.3/dialog/oauth?client_id="+appId+"&display=popup&response_type=token&redirect_uri=https://www.facebook.com/connect/login_success.html"
InAppBrowser.isAvailable()
.then(() => {
InAppBrowser.openAuth(url, redirectUri, {
// iOS Properties
dismissButtonStyle: 'cancel',
// Android Properties
showTitle: false,
enableUrlBarHiding: true,
enableDefaultShare: true,
})
.then((response) => {
// Only gets to this point if user explicitly cancels.
// So this does not trigger upon successful login.
})
// catch handlers follow
Using the above, my app correctly open up an in-app browser and I can login fine using a test user for my test app. Upon successful login though, I don't get redirected back to the .then completion handler. It just stays in the in-app browser view and I see the same message from Facebook that I see when logging in using a web browser. It says something like "Success. Please treat the url the same as you would a password", or something like that.
I may be missing something here, but I thought the purpose of passing redirectUri as an argument to openAuth was so that upon redirection to that URI, the completion handler would be triggered.
Question: How do I redirect back to the completion handler upon login success?
I think that you already have a solution but thought it might be useful for someone else facing this issue. If you don't have a solution so far follow my instructions:
You can't directly redirect back to your application using deep link, since Facebook will not call a link `like myapplicationname://mycustompath´. It's only possible to call links using the https-protocol (https://...).
The solution I'd suggest you to use is to redirect using your own API (Facebook -> Your API -> Deep Link Redirection). You will understand why this is required in the most of the real world applications at the end of the instructions.
Starting from your react-native app call the authorize endpoint of Facebook with a redirection to your application and set the global deeplink of your app as redirect uri.
InAppBrowser.close();
InAppBrowser.openAuth("https://graph.facebook.com/oauth/authorize?client_id=YOURCLIENTID&redirect_uri=https://YOURDOMAIN:PORT/auth/facebook", "{YOURAPPSDEEPLINKNAME}://{SOMEPATHYOUWANTTOEND}")
.then((response) => {
handleAuthorized(response, LOGINTYPE.FACEBOOK);
});
Now after login you'll be redirected to your API with the authorization code token as query parameter (e.g. https://YOURDOMAIN:PORT/auth/facebook?code=AVERYLONGCODESENTBYFACEBOOK)
Using this code token from the query parameter, you make another API Call to get the access_token for the user
{GET}: https://graph.facebook.com/v15.0/oauth/access_token?client_id=YOUR_CLIENT_ID&redirect_uri=https://YOURDOMAIN:PORT/auth/facebook&client_secret=YOUR_CLIENT_SECRET&code=AVERYLONGCODESENTBYFACEBOOK
Facebook's API will send you an answer as JSON with the access_token inside.
You can make another call using the access token of the user, to get the userId and the username
{GET}: https://graph.facebook.com/me?access_token=ACCESS_TOKEN_SENT_BY_FACEBOOK_IN_PREVIOUS_GET_REQUEST.
If you need the e-mail address for the user you have to make another call. Make sure you'd set the permission to read the e-mail address for your app on the developer portal of facebook.
The following request will return you the id, name and the email of the user
{GET}: https://graph.facebook.com/USERIDFROMPREVIOUSREQUEST?fields=id,name,email&access_token=ACCESSTOKEN
I think you want to save all these information to a database and create a session in order to keep the user logged in and therefore all the requests described will be useful for you in a real application.
After doing all the backend stuff, you're ready for the redirection using deep link. To do that, set a meta-tag to redirect the inappbrowser to your application:
<meta http-equiv="refresh" content="0; URL={YOURAPPSDEEPLINKNAME}://{SOMEPATHYOUWANTTOEND}" />

Default reset password email not sent via Appcelerator backend, nor emails with a template, only email configuration changes are sent

When I execute the following code,
Cloud.Users.requestResetPassword({
email: myUsersEmailAddress
}, function (e) {
if (e.success) {
Ti.API.info('Success: Reset Request Sent ' + JSON.stringify(e));
} else {
Ti.API.error('Error:\n' + ((e.error && e.message) || JSON.stringify(e)));
}
});
I should receive an email to reset my password, as seen in the documentation:
GET users/request_reset_password.json Sends an email to a user
containing a link to recover a lost password. You can use the default
email template provided by ACS, or specify a custom email template
that you have created. When using a custom email template, the email
must contain a properly formatted URL, as explained in the template
method parameter documentation below.
When the alert pops up, I can see that there was a match and that an email should have been sent.
However, I do not receive an email, nor do I see anything in the logs of my email backend (which does receive an email when I adapt my email configuration on the appc backend, thus my email is correctly configured)
I don't have any email templates configured, but according to the documentation it should use appc's default reset password email.
Does anyone has an idea about what I am doing wrong, or does this indicate an issue with appc's documentation or backend?
UPDATE: I have another function which sends email using a self-defined email template. When I invoke this function, i receive the following event(between the {}):
[INFO] : Deactivation email sent. {"success":true,"error":false,"meta":{"status":"ok","code":200,"method_name":"emailFromTemplate"}}
However, nothing is seen on our smtp backend. The only things we do see (and which we receive in our mailbox) are the emails which are sent when you adapt your email configuration settings in Appcelerator's backend, eg.
Subject: Appcelerator Cloud Services SMTP Test
Appcelerator Logo Hi Peter,
Your SMTP settings have been updated successfully!
Onward,
The Appcelerator Platform Team
Thanks,
David
It turned out to be a configuration issue, which could only be discovered by doing some curl calls against the api. So a good advice, test your config with curl too, and don't rely on the emails which are sent after you made a configuration change!