Testing Branch.IO referral links on react native - react-native

We use branch for referrals in our react native application. I have implemented branch successfully, now I want to test some scenarios.
When we click on a referral link, it navigates to app store or play store. But I want to do some debugging to identify if the params I pass are successfully send or not.
I have subscribed it like this. But how can I debug this with react-native debugger to see the console logs?
BranchIO.subscribe(async ({ error, params }) => {
if (error) {
console.log('Error from Branch: ', error);
return;
}
// Handle non-Branch URL.
if (params['+non_branch_link']) return;
// Indicates initialization success.
// No link was opened.
if (!params['+clicked_branch_link']) return;
const installParams = await BranchIO.getFirstReferringParams();
if (installParams?.$canonical_identifier === DeepLinkTypes.referral) {
store.dispatch(setReferralKey(installParams.referralKey));
}
// A Branch link was opened.
// Route link based on data in params
navigatePath(params.$deeplink_path);
});

To debug if you are able to fetch the associated link data or not you can put in a debugger at the following line-
const installParams = await BranchIO.getFirstReferringParams();
Also we would suggest you to kindly use/update the above line to use getLatestReferringParams
let lastParams = await branch.getLatestReferringParams()
instead of getFirstReferringParams() since there are some recent issues reported lately with this method.
You can print out the parameters in the console and see for the link data.

Related

Abort an Updates.fetchUpdateAsync() after a certain time [Expo/React native]

Expo React Native SDK Version: 46
Platforms: Android/iOS
Package concerned : Expo.Updates
Hello everyone, I want to programmatically check for new updates, without using the fallbackToCacheTimeout in app.json that will trigger the check of the new updates when the application is launched because like that I can't put a custom loading page.
So by doing this all by code as follow :
try{
const update = await Updates.checkForUpdateAsync();
if(update.isAvailable){
await Updates.fetchUpdateAsync();
await Updates.reloadAsync();
}else{}
}catch(err){}
But I want to be able to abort all those calls after a certain time (thus, the user that have a bad connection can use the app without waiting a very long time).
I check the documentation and I cannot found any method that allow this.
I dont't think it's possible to cancel a Promise for now in Javascript, or maybe any connection ?
Or does the "fallbackToCacheTimeout" value in the app.json will automatically apply to the fetch updates call of the Expo API?
Do someone have any idea how to do it ? :(
First of all I am assuming you have set updates.checkautomatically field to ON_ERROR_RECOVERY in app.json or app.config.js file. If not, please check the documentation. The reason why you need this is to avoid automatic updates which can also block your app on splash screen.
Updated Solution
Because of the limitation in javascript we can't cancel any external Promise (not created by us or when its reject method is not exposed to us). Also the function fetchUpdateAsync exposed to us is not a promise but rather contains fetch promise and returns its result.
So, here we have two options:
Cancel reloading the app to update after a timeout.
But note that updates will be fetched in background and stored on
the device. Next time whenever user restarts the app, update will
be installed. I think this is just fine as this approach doesn't
block anything for user and also there is a default timeout for http
request clients like fetch and axios so, request will error out in
case of poor/no internet connection.
Here is the code:
try {
const update = await Updates.checkForUpdateAsync();
if (update.isAvailable) {
const updateFetchPromise = Updates.fetchUpdateAsync();
const timeoutInMillis = 10000; // 10 seconds
const timeoutPromise = new Promise((_, reject) => setTimeout(() => reject("timedout"), timeoutInMillis))
// This will return only one Promise
Promise.race([updateFetchPromise, timeoutPromise])
.then(() => Updates.reloadAsync())
.catch((error) => {
if (error === 'timedout') {
// Here you can show some toast as well
console.log("Updates were not cancelled but reload is stopped.")
} else if (error === 'someKnownError') {
// Handle error
} else {
// Log error and/or show a toast message
}
})
} else {
// Perform some action when update is not available
}
} catch (err) {
// Handle error
}
Change the expo-updates package just for your app using a patch
Here you can return a cancel method with Updates.fetchUpdateAsync() and use it with setTimeout to cancel the fetch request. I won't be providing any code for this part but if you are curious I can definitely provide some help.
Please refer this section to understand use of fallbackToCacheTimeout in eas updates.
Old solution:
Now, for aborting or bypassing the promise i.e. Updates.fetchUpdateAsync in your case. You can basically throw an Error in setTimeout after whatever time duration you want, so that, catch block will be executed, bypassing the promises.
Here is the old code :
try{
const update = await Updates.checkForUpdateAsync();
if(update.isAvailable){
// Throw error after 10 seconds.
const timeout = setTimeout(() => { throw Error("Unable to fetch updates. Skipping..") }, 10000)
await Updates.fetchUpdateAsync();
// Just cancel the above timeout so, no error is thrown.
clearTimeout(timeout)
await Updates.reloadAsync();
}else{}
}catch(err){}

Given oauth_app resource not found - Magic.Link

I tries to integrate magic link social authentication to my React Native Mobile app and it always gives error Given oauth_app resource not found as in the attached file.
I use the code as described in the documentation and they're as follows,
const MagicElement = new Magic('pk_test_***********', {
extensions: [new OAuthExtension()],
});
try {
const result = await MagicElement.oauth.loginWithPopup({
provider: 'apple' /* 'google', 'facebook', 'apple', or 'github' */,
redirectURI: 'testapp://demo/your/oauth/callback',
});
console.log('result', result)
} catch (error) {
console.log('error', error)
}
}
https://docs.magic.link/client-sdk/web/social-login
Appreciate if anyone can help to solve this issue.
Be careful what parameters you are passing to loginWithPopup etc. An easy step to take if you encounter this screen is to look at the network tab filtered on "document" type.
In my case [object%20Object] in the request URL was a giveway:
https://auth.magic.link/v1/oauth2/[object%20Object]/start?magic_api_key=...
After fixing the parameters the URL became something like
https://auth.magic.link/v1/oauth2/google/start?magic_api_key=...
and the error went away.

Identify the sender after the app installation with branch referrals with react-native

In my React-Native application I use branch.io to handle referrals. Deep links are generated successfully through the app and can be shared it to the others.
Issue is, if the receiver hasn't installed the app yet, once the dynamic link is received, after clicking on that, he will go to the appstore/playstore and install the app.
After the installation, I want to identify the sender of the deeplink. My subscribe to branch is like this.
BranchIO.subscribe(async ({ error, params }) => {
if (error) {
console.log('Error from Branch: ', error);
return;
}
if (params['+non_branch_link']) return;
if (!params['+clicked_branch_link']) return;
if (params.$canonical_identifier === DeepLinkTypes.referral) {
store.dispatch(setReferralKey(params.referralKey));
}
const lastParams = await BranchIO.getLatestReferringParams();
const installParams = await BranchIO.getFirstReferringParams();
console.log(lastParams);
console.log(installParams);
navigatePath(params.$deeplink_path);
});
How should I access these params after a new install of the app? I mean, once the receiver clicks on the link and goes to playstore/appstore, does branch track this? Once the inatalled app is loaded, shall we access the relevant data through params?
Yes deferred deep linking is supported with Branch. For React Native you can read the parameters like this - \
branch.subscribe(({error, params, uri}) => {
if (error) {
console.error('Error from Branch: ' + error)
return
}
// params will never be null if error is null
})
let lastParams = await branch.getLatestReferringParams() // params from last open
let installParams = await branch.getFirstReferringParams() // params from original install
Make sure you get the params after calling branch.subsribe().Here is the documentation for the same - https://help.branch.io/developers-hub/docs/react-native#section-read-deep-link

Expo - Continue Upload on if component unmount

In my react native (Expo) application the user has the possibility to select images for a group from the gallery to upload them to the server.
When the User selects the images in the Mediapicker Screen i store the list of the uris in the Asyncstorage and navigate back to the "group screen".
Here i read the data from the asyncstorage
_retrieveUpload = async () => {
try {
const value = await AsyncStorage.getItem("upload_que");
if (value !== null) {
this.setState({ uploadQueue: JSON.parse(value) });
}
} catch (error) {
console.log(error);
}
};
in the next step i created a component which takes this.state.uploadQueue as property, iterate over the values and upload them to the server.
This is working as long as the component is mounted and the user does not leave the screen.
I read that there is no possibility for a background-task in expo, but how can i start something like a service which runs independent from the actual mounted component?
First of all, can you post you Upload Component source code for more details.
Also please try in your upload code if you have await syntax, remove it and work with 'promise' and 'then' syntax if you need to do something after upload.

how to handle axios onError in nuxtjs plugin and show appropriate error message to user

I have a nuxt single page application. The api that I work with has a list of codes for various errors. So, in onError interceptor, the error has to be checked in a dictionary or in a more desired way in a json file. For this, I added a error-handler.js plugin in my nuxt project. But, I don't know how to read from json file.
1) Loading of the json file would occur every time an error thrown?
2) What is the best practice to show the error message to the user? Is this plugin only responsible to create the error-message and in the page try-catch is needed to toast that message?
export default function ({ $axios, store, app, redirect }) {
$axios.onError(error => {
if (error.config.hasOwnProperty('errorHandle') && error.config.errorHandle === false) {
return Promise.reject(error);
}
if (error.message === 'Network Error') {
error.message = 'check the Internet connection';
return
}
const code = parseInt(error.response && error.response.status)
if (error.response)
console.log('error.response', error.response.status, error.response)
if (error.response.data.Errors) {
let errMessage = ''
error.response.data.Errors.forEach(item => {
switch (item.Message.MessageText) {
case 'OrganizationNotFound':
errMessage = 'the organization that you are looking for does not exists'
break
}
})
}
}
}
In Nuxt, plugin code is loaded once or twice per user visit, after that in universal mode it is not executed (of course your onError handler will be). It's once if you make it a client/server-side only plugin, or twice if you need it both on client and server. In your case client-side only plugin sounds like a good choice - just make sure that loading of JSON goes outside of the onError function.
As for how to show it, it depends on your design. We are using Vuetify and have v-snackbar in default layout so it's on every page. Snackbar is bound to VueX value. Then your error plugin can populate that value as appropriate as it will have access to store. This keeps the "raising the error" (dispatch to store) and "showing the error" reasonably decoupled, whilst very reusable (components can also dispatch to store if they face a problem).