Why is my universal route not working? Or what is it actually doing? - react-native

I am setting a universal link with a React Native app. It is routing to my app, but I am not getting the behavior that I expect.
Here is the component piece of my AASA file.
"components": [
{
"#": "no_universal_links",
"exclude": true,
"comment": ""
},
{
"/": "/oauth*",
"comment": "Redirect URL for OAuth"
}
]
The AASA file is hosted at a url that I own. I have installed the app on my phone, pulled the sysdiagnose file off my device and verified that my app is downloading the AASA file, so the routes should be working on my device.
In my React Native code, I have an event watcher looking at the urls that are being used to open the app. I am using the expo-linking library to log the url and params.
function handleLink(event) {
const data = Linking.parse(event.url);
console.log(data, data);
}
React.useEffect(() => {
Linking.getInitialURL().then((res) => {
console.log(res);
});
const listener = Linking.addEventListener("url", handleLink);
return () => listener.remove();
}, []);
When I route to <url>/oauth in safari, it gives the options to open up my app. When I use the app option the system then routes to my app. The code above then logs out the url and query params from the url that opened the app.
When I try to use the universal link for the actual OAuth redirect (not from Safari), it opens up my app, but no url is logged out from the event, so the event is not being hit at all. Also, it looks like it is opening up some kind of webpage in my app, but the fact is I really don't know what it is doing.
In short, when using my app with another service calling the url, it opens up my app, but I only see a white page and only know I am on my app by looking at the title of the app.
If anyone could give me any direction, I would be really grateful.

Related

react native supabase facebook login redirect callback site url

I am trying to login with facebook using Supabase on ios emulator. After logging in with Facebook, it redirects me back to localhost. I don't know exactly what to do on this side. Can you help me? I'm still very new.
const onHandleLogin = async () => {
const {data, error} = await supabase.auth.signInWithOAuth({
provider: 'facebook',
});
if (error) {
return;
}
if (data.url) {
const supported = await Linking.canOpenURL(data.url);
if (supported) {
await Linking.openURL(data.url);
}
}
};
After the login process, it still stays on the localhost address on the browser. My purpose is to send it to the application and get token information via the url, but I have no idea how.
I think I need to make changes here but I don't know what to write in the site url because it is a mobile application.
Thanks for your support and replies.
I tried to login with facebook using supabase, but after logging in, it keeps me in safari and gives token information on localhost. I want to direct the application after the login process and get the token information.
You will need to create a deep link for your React Native app: https://reactnative.dev/docs/linking and then set this as your redirect URL. Here a similar example with Flutter: https://supabase.com/docs/guides/getting-started/tutorials/with-flutter#setup-deep-links

Expo Go with Google/Facebook OAuth - auth.expo.io login screen - "Not Found"

I am trying to set up google oauth in a react native, expo managed app. I am only having the following issue using my app within Expo Go - when I create a build of the app, the oauth flow works perfectly. But its hard to develop that way, and I need to be able to share a working app with non-dev team members via Expo Go. I have set up the flow in what I think is the same as what the expo go google auth documentation has described. An overview
Create a project in google console, and set up a new ClientID for web applications. Set the authorized origins and redirect uri:
Where myorg is the name of the expo organizational account that owns the project, and projectname is the same value as slug in app.json.
After setting this up, I get the client id, and client secret for this oauth login method.
In my app code, I follow the instructions to use the expo-auth-session library for google:
import * as WebBrowser from "expo-web-browser";
import * as Google from "expo-auth-session/providers/google";
WebBrowser.maybeCompleteAuthSession();
export const OAuthButtons: React.FC = () => {
const [request, response, promptAsync] = Google.useAuthRequest({
expoClientId: "clientId-from-google-console.apps.googleusercontent.com",
iosClientId: "will set this up eventually",
androidClientId: "will set this up eventually",
});
return; // markup for sign in buttons
}
So now in my app, when I click the google sign in button, I get the prompt to open the web browser correctly:
Clicking that correctly opens the expo web browser, but I see a "not found" message:
For more details, when I log the request, I get some pretty expected values
"{
"url": "https://accounts.google.com/o/oauth2/v2/auth?redirect_uri=https%3A%2F%2Fauth.expo.io%2FMyProject&client_id=id-from-console.apps.googleusercontent.com&response_type=token&state=5xWG83SsoJ&scope=openid%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email",
"responseType": "token",
"clientId": "client-id-from-console.apps.googleusercontent.com",
"redirectUri": "https://auth.expo.io/MyProject",
"scopes": [
"openid",
"https://www.googleapis.com/auth/userinfo.profile",
"https://www.googleapis.com/auth/userinfo.email"
],
"state": "5xWG83SsoJ",
"extraParams": {},
"codeChallengeMethod": "S256",
"usePKCE": false
}"
The only values here that are a bit unexpected are the redirectUri and redirect_uri, which have a /MyProject appended to them, which is not exactly what I had put in my redirect uri in the google console. How did that get appended there? Might that be the problem?
As far as I can tell, I've set everything up as described. What is it exactly that is "Not Found" here? The oauth page for this particular expo application? Where did I go wrong in my setup?
Edit - Same Problem with Facebook.useAuthRequest
I am having the same exact problem with the Facebook provider module as well. Similar code:
const [facebookRequest, facebookResponse, facebookPromptAsync] =
Facebook.useAuthRequest({
clientId: "facebook_app_id",
responseType: ResponseType.Code,
});
I also tried the suggestion from the article Use expo-auth-session with Facebook the Easiest Way on iOS/Android to add the useProxy: true property, but that makes no difference.
const [facebookRequest, facebookResponse, facebookPromptAsync] =
Facebook.useAuthRequest(
{
clientId: "facebook_app_id",
responseType: ResponseType.Code,
},
{ useProxy: true }
);
The facebook login also opens the expo browser to an empty page that says "Not found"
What am I doing wrong here?
Do you have your originalFullName specify on your app.json? If not, try to add it e.g originalFullName: "#your_username/your_app_name"
And maybe this github issue can help you, https://github.com/expo/expo/issues/19891.

Is it possible to pass referer URL in the request header to React Native App using Deep Linking?

My React Native app has a website version. When an user click a link to our website, it will open my App using Deep links. Now I want to send some data from that url to my app, specifically the referer field in request header (for tracking tool search, like google.com, etc. ). I already have this piece of code in my app :
useEffect(() => {
const subscription = Linking.addEventListener('url', navigateScreen);
//navigateScreen is a function to navigate to screen of my App depending on url
return () => {
if (subscription) {
subscription?.remove();
}
};
}, [navigateScreen]);
So my question is can I have my App receive the request header of url or only the url itself ? If can how can I achieve it ?

Stripe Connect Account - return_url - Link back to Expo application

I'm on-boarding users onto Stripe connect. My node server generates a temporary HTTPS URL so that customers can sign on. According to their docs I need to provide a URL for when they complete the application.
https://stripe.com/docs/api/account_links/create#create_account_link
I have an Expo application. The user will open up the URL in their browser. However when they complete their application I would like them to go back to Expo App. If I try to use expo://MYAPP/ as the return_url, Stripe does not recognize the URL schema.
Does anyone have an idea how i can return the user back into my application after completing their on-boarding done via the browser?
For anyone one out there who runs into this post, this is was my solution. Your app has to link to a website. I am using Expo, but this is the React code to generate the link.
import * as WebBrowser from 'expo-web-browser';
import * as Linking from 'expo-linking';
const openPage = async () => {
try {
const result = await WebBrowser.openAuthSessionAsync(
`${url}?linkingUri=${Linking.createURL('/?')}`,
);
let redirectData;
if (result.url) {
redirectData = Linking.parse(result.url);
}
setstate({ result, redirectData });
} catch (error) {
console.log(error);
}
};
When you load the site, make sure to pass the URL that was generated from your backend
Backend code:
stripe.accountLinks
.create({
type: 'account_onboarding',
account: accountID,
refresh_url: `https://website.com/refresh`,
return_url: `https://website.com/return`,
})
When the user has the site open, have a button that redirects to the stripe URL.This is how i thought it went first
App -> Stripe connect
instead you have to approach it like this
App -> Website -> Stripe connect

Linking in react native can open just one app

UPDATE 1
I removed return from code and now links work on IOS.
But on android I can't open any app. Any idea?
I am trying to open different apps from my app.
return Linking.openURL(“twitter://“);
return Linking.openURL(“instagram://“);
But it doesn’t work. I configured IOS by documentation. On android doesn’t work too. While...
return Linking.openURL(“tripadvisor://“);
Work just fine.
Any idea why I can’t open other apps.
This is code that I am using (open app if installed or open store with it but sometimes even store doesn't open) what I did wrong:
let appUrl = "instagram://";
Linking.canOpenURL(appUrl).then(supported => {
if (!supported) {
Alert.alert("",
"",
[
{text: "go to store", onPress: this.openStorePress},
{text: "cancel", onPress: () => { }, style: 'cancel'},
],
{ cancelable: false }
);
} else {
return Linking.openURL(appUrl);
}
}).catch(err => {
console.error(err);
});
Your issue is related to the content of the url, twitter:// means nothing for the Android Twitter app, so it will not open.
For example, the following code should work:
Linking.openURL('twitter://timeline')
or
Linking.openURL('instagram://user?username=apple')
You have to find the rights url schemes (documentations are not very clear about it) that may be different between iOS and Android.
Twitter: How can I open a Twitter tweet using the native Twitter app on iOS?
Instagram: https://www.instagram.com/developer/mobile-sharing/iphone-hooks/ (all do not work on Android)
misc: https://pureoxygenlabs.com/10-app-url-schemes-for-marketers/
You have to find the rights URL schemes. Have look at my code
Instagram
Linking.openURL('instagram://user?username=apple')
.catch(() => {
Linking.openURL('https://www.instagram.com/apple');
})
Twitter
Linking.openURL('twitter://user?screen_name=apple')
.catch(() => {
Linking.openURL('https://www.twitter.com/apple');
})
Facebook
Linking.openURL('fb://page/PAGE_ID');
Linking.openURL('http://instagram.com/_u/USER_NAME');
Linking.openURL('http://instagram.com/_p/PICTURE');
Your code looks pretty solid, here's an example of how I open twitter in my app.
const twitterUrlScheme = `twitter://user?screen_name=${twitterUsername}`;
Linking.canOpenURL(twitterUrlScheme)
.then((supported) =>
Linking.openURL(
supported
? twitterUrlScheme
: `https://www.twitter.com/${twitterUsername}`
)
)
.catch((err) => console.error('An error occurred', err));
I think perhaps your issue might be the return Linking.openUrl, I'm not sure you need the return in that statement. Does it work if you remove the return? Otherwise, it might help to move your Alert outside of the then-block from canOpenUrl.
I have used only url and it's working both iOS and android
Linking.openURL('https://www.facebook.com/');
You haven't completed the " fot twitter and instagram, I don't know whether you made the same mistake in app too, if yes, fixing that might solve it.
Try to use a package like:
https://github.com/react-native-community/react-native-share
You can try to use only some of it's functions or look into the native code from there and create some bridge functions in the native code and then export them to be used in JS code.
Note: you will have to use real devices for the tests.