React Native - Parse URL to get Query Variable - react-native

Looking for a way to parse a URL to get a query variable in React Native received from Linking.
I'm receiving the URL as something like:
url-app-scheme://somePage?someVar=someVal
I'd like to get the someVar value from the URL.
Any thoughts?

This should do the trick
var url = "http://example.com?myVar=test&otherVariable=someData&number=123"
var regex = /[?&]([^=#]+)=([^&#]*)/g,
params = {},
match;
while (match = regex.exec(url)) {
params[match[1]] = match[2];
}
console.log(params)

There is a URL class in JavaScript which is intended to let you both build and parse URLs robustly, making query parameters easily accessible:
const url = new URL('url-app-scheme://somePage?someVar=someVal');
url.searchParams.get('someVar')
Sadly, the implementation of URL in React Native is not complete and has some known bugs. Fortunately, there is a solid polyfill library called react-native-url-polyfill which provides an implementation of URL that is well behaved and tested - I highly recommend it.

Using query-string its working
yarn add query-string
import queryString from 'query-string';
const parsed = queryString.parseUrl("https://pokeapi.co/api/v2/pokemon?offset=10&limit=10");
console.log(parsed.query.offset) will display 10

There are ways of doing this that you can leverage from the JS ecosystem. Try URI.js https://github.com/medialize/URI.js

Try url https://www.npmjs.com/package/url
"This module has utilities for URL resolution and parsing meant to have feature parity with node.js core url module."
The node URL object is available to your app when using the Chrome react-native debugger, but is not available on your iPhone when untethered.
So use this package
npm install url
Sample code:
import url from 'url';
...
let urlObject = url.parse(inUrlString);
let outUrlString = urlObject.protocol + '//' + urlObject.host + '/more/jump?jump_path=' + encodeURIComponent(urlObject.pathname);

url="example.com/path/?id=1"
let urlObject = url.parse(url, true); // second parameter `true` (parse search query)
console.log(urlObject.query['id']); // 1

Update: This is not a solution to the above question because it doesn't work unless in debugging mode. I have not deleted this answer however, because I think it points out a note worthy nuance.
JavaScript's very own URL Web API is supported in React Native (using version 0.46). You can use to to parse or build any and every part of the url with great ease.
The API is identical to the WHATWG API of the URL module in Node.js This answer should really be more obvious, but its easy to get lost with the number of okay url parsing packages available.
Edit: This works only in the JS debugging mode for some reason, and not otherwise. So this solution doesn't really hold valid, but I'm leaving it here because I'd love to know how to get the same URL module to work with react-native.

Related

what is the significance of setFrequency() function in titanium Js v7.5.0

I have been facing an issue regarding Geolocation in iOS/Android app. I am using Titanium Js and have upgraded Ti v7.5.0 to v8.3.1. I checked my legacy code and came to know that this below function
Titanium.Geolocation.setFrequency()
creating a problem. It seems like this function gets deprecated.
this.locationFrequency = 100;
Geolocate.prototype.getCurrentPosition = function(callback){
var self = this;
// initialize the callback
this.locationReceivedCallback = callback;
// Set this so we get updates rapidly
Titanium.Geolocation.setFrequency(this.locationFrequency)
// Register for the actual event
Titanium.Geolocation.addEventListener('location', someCallBackFunc);
};
Now, I need help to understand what actually this Titanium.Geolocation.setFrequency() does. Is there any alternate way to achieve the same in latest version of Ti?
Since it is open source you can look at the github repo:
https://github.com/appcelerator/titanium_mobile/blob/7_5_X/android/modules/geolocation/src/java/ti/modules/titanium/geolocation/GeolocationModule.java#L469
and check the official documentation at frequency
https://docs.appcelerator.com/platform/latest/?print=/api/Titanium.Geolocation#property-frequency and use the recommendation there.

Is there a way I can detect text from an Image using Expo React Native?

I am working with Expo, React Native and I want to to be able to detect text from images. Is there an package i can work with to achieve this?
I am using Expo camera module to snap the picture and supply the URI to the text detector
I have tried using react-native-text-detector but I am getting the error that the function detectFromUri is not defined. I have also tried with tesserect.js but it fails on import with "unable to resolve variable location".
await this.camera.takePictureAsync(options).then(photo => {
photo.exif.Orientation = 1;
//console.log(photo.uri);
const visionResp = await RNTextDetector.detectFromUri(photo.uri);
if (!(visionResp && visionResp.length > 0)) {
throw "UNMATCHED";
}
console.log(visionResp);
});
I am expecting the visionResp to log the results returned from the detection but instead i get undefined is not an object (evaluating '_reactNativeTextDetector.default.detectFromUri')
Is your project created with expo-cli?
If yes, Expo is not supporting OCR currently. There is a feature request on canny.io but you can't know for sure when it will become available.
Your only choice is to use an OCR service like this one.Internet connectivity will be required.
If not, (and the project is created with react-native-cli) you should be able to successfully use react-native-text-detector. Just make sure you link the package correctly. Docs here

SystemJS with React native

I want to use systemjs inside react-native.
When I use following code in the browser systemjs register itself with global/window.
fetch('https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.18.17/system.src.js')
.then(response => response.text())
.then(txt => {
eval(txt);
})
.catch(ex => {
console.log(ex);
});
I executed same code in expo AwesomeProject on the homescreen component and the above code does not throw any exceptions, but when I try to render all the globally registered objects I don't see SystemJs/System.
First question I have - Is it even possible to register systemjs and use it with react-native?
If the answer to first question is yes, then is it the correct way to eval(Systemjs)?
If not is there any other method I can use to access system js?
I have seen couple of projects on github like react-native-eval and react auto updater, but that is not what I want.
Anyone can give me some insight?
I will answer my own question.
Yes it is possible to load systemjs in React native.
Simple eval will evaluate the systemjs code, but you might get some errors. I am not an expert in the internals of systemjs but it seems it tries to run in some context, either a browser or in some cases a node server.
I received an error in following code.
var vmModule = 'vm';
var vm = require(vmModule);
I had to tweak my code a little bit and supply a fake require function and I was able to load systemjs.

Add element to Firestore array

Currently, I have an empty array in Firestore dashboard. And I'm trying to add some item to it. I've followed this, but no result. I don't want to sore and rewrite this element.
My gradle contains:
implementation 'com.google.firebase:firebase-firestore:17.0.4'
and my code:
import com.google.firebase.firestore.FieldValue
...
val documentReference = firestore.collection("events")
.document(event.firebaseUserUid + "-" + event.title)
documentReference
.update("participants", (FieldValue.arrayUnion(FirebaseAuth.getInstance().currentUser!!.uid)) )
But FieldValue.arrayUnion doesn't exists.
I don't think support for that has actually been added to the Android API, despite its documentation as such on the page you linked.
It's missing from the Android API documentation, but is present in the Web API documentation as well as the Web changelog.
Newest version of firestore now supports it:
implementation 'com.google.firebase:firebase-firestore:17.1.0'

Reliably getting favicons in Chrome extensions, chrome://favicon?

I'm using the chrome://favicon/ in my Google Chrome extension to get the favicon for RSS feeds. What I do is get the base path of linked page, and append it to chrome://favicon/http://<domainpath>.
It's working really unreliably. A lot of the time it's reporting the standard "no-favicon"-icon, even when the page really has a favicon. There is almost 0 documentation regarding the chrome://favicon mechanism, so it's difficult to understand how it actually works. Is it just a cache of links that have been visited? Is it possible to detect if there was an icon or not?
From some simple testing it's just a cache of favicons for pages you have visited. So if I subscribe to dribbble.com's RSS feed, it won't show a favicon in my extension. Then if I visit chrome://favicon/http://dribbble.com/ it won't return right icon. Then I open dribbble.com in another tab, it shows its icon in the tab, then when I reload the chrome://favicon/http://dribbble.com/-tab, it will return the correct favicon. Then I open my extensions popup and it still shows the standard icon. But if I then restart Chrome it will get the correct icon everywhere.
Now that's just from some basic research, and doesn't get me any closer to a solution. So my question is: Is the chrome://favicon/ a correct use-case for what I'm doing. Is there any documentation for it? And what is this its intended behavior?
I've seen this problem as well and it's really obnoxious.
From what I can tell, Chrome populates the chrome://favicon/ cache after you visit a URL (omitting the #hash part of the URL if any). It appears to usually populate this cache sometime after a page is completely loaded. If you try to access chrome://favicon/http://yoururl.com before the associated page is completely loaded you will often get back the default 'globe icon'. Subsequently refreshing the page you're displaying the icon(s) on will then fix them.
So, if you can, possibly just refreshing the page you're displaying the icons on just prior to displaying it to the user may serve as a fix.
In my use case, I am actually opening tabs which I want to obtain the favicons from. So far the most reliable approach I have found to obtain them looks roughly like this:
chrome.webNavigation.onCompleted.addListener(onCompleted);
function onCompleted(details)
{
if (details.frameId > 0)
{
// we don't care about activity occurring within a subframe of a tab
return;
}
chrome.tabs.get(details.tabId, function(tab) {
var url = tab.url ? tab.url.replace(/#.*$/, '') : ''; // drop #hash
var favicon;
var delay;
if (tab.favIconUrl && tab.favIconUrl != ''
&& tab.favIconUrl.indexOf('chrome://favicon/') == -1) {
// favicon appears to be a normal url
favicon = tab.favIconUrl;
delay = 0;
}
else {
// couldn't obtain favicon as a normal url, try chrome://favicon/url
favicon = 'chrome://favicon/' + url;
delay = 100; // larger values will probably be more reliable
}
setTimeout(function() {
/// set favicon wherever it needs to be set here
console.log('delay', delay, 'tabId', tab.id, 'favicon', favicon);
}, delay);
});
}
This approach returns the correct favicon about 95% of the time for new URLs, using delay=100. Increasing the delay if you can accept it will increase the reliability (I'm using 1500ms for my use case and it misses <1% of the time on new URLs; this reliability worsens when many tabs are being opened simultaneously). Obviously this is a pretty imprecise way of making it work but it is the best method I've figured out so far.
Another possible approach is to instead pull favicons from http://www.google.com/s2/favicons?domain=somedomain.com. I don't like this approach very much as it requires accessing the external network, relies on a service that has no guarantee of being up, and is itself somewhat unreliable; I have seen it inconsistently return the "globe" icon for a www.domain.com URL yet return the proper icon for just domain.com.
Hope this helps in some way.
As of Oct 2020, it appears chrome extensions using manifest version 3 are no longer able to access chrome://favicon/* urls. I haven't found the 'dedicated API' the message refers to.
Manifest v3 and higher extensions will not have access to the
chrome://favicon host; instead, we'll provide a dedicated API
permission and different URL. This results in being able to
tighten our permissions around the chrome:-scheme.
In order to use chrome://favicon/some-site in extension. manifest.json need to be updated:
"permissions": ["chrome://favicon/"],
"content_security_policy": "img-src chrome://favicon;"
Test on Version 63.0.3239.132 (Official Build) (64-bit)
chrome://favicon url is deprecated in favor of new favicon API with manifest v3.
// manifest.json
{
"permissions": ["favicon"]
}
// utils.js
function getFaviconUrl(url) {
return `chrome-extension://${chrome.runtime.id}/_favicon/?pageUrl=${encodeURIComponent(url)}&size=32`;
}
Source: https://groups.google.com/a/chromium.org/g/chromium-extensions/c/qS1rVpQVl8o/m/qmg1M13wBAAJ
I inspected the website-icon in Chrome history page and found this simpler method.
You can get the favicon url by --
favIconURL = "chrome://favicon/size/16#1x/" + tab.url;
Don't forget to add "permissions" and "content_security_policy" to Chrome. (https://stackoverflow.com/a/48304708/9586876)
In the latest version of Chrome, Version 78.0.3904.87 (Official Build) (64-bit)) when tested, adding just img-src chrome://favicon; as content_security_policy will still show 2 warnings:
'content_security_policy': CSP directive 'script-src' must be specified (either explicitly, or implicitly via 'default-src') and must whitelist only secure resources.
And:
'content_security_policy': CSP directive 'object-src' must be specified (either explicitly, or implicitly via 'default-src') and must whitelist only secure resources.
To get rid of them use:
"permissions": ["chrome://favicon/"],
"content_security_policy": "script-src 'self'; object-src 'self'; img-src chrome://favicon;"
Now you can use chrome://favicon/http://example.com without getting any errors or warnings.