I am opening this question and answering it myself to help other users that face the same issue.
Working with a React Native app in Android that uses the package react-native-geolocation-service, when trying to get the user to activate its location (not to allow it, to activate it), I found that the button cancel wasn't returning any errors. Here is the pop up I'm talking about:
The function I was using was the following:
Geolocation.getCurrentPosition(
(position) => {
console.log(position);
(error) => {
console.log(error.code, error.message);
},
{ enableHighAccuracy: true, timeout: 15000, maximumAge: 10000 }
});
I was completely sure it was correct, because it was a copy from github's repo. But then, the console never logged the error.
If you are facing the same issue, check the answer below.
Turns out, the problem was that a combination of Visual Studio Code pluggins (Prettier and ESLint probably) messed up with my code. The correct code should look like this:
Geolocation.getCurrentPosition(
pos => {
// Do somehting if location activated
},
error => {
console.log(error.code, error.message);
},
{enableHighAccuracy: false, timeout: 15000, maximumAge: 10000}
);
As you can see, all of my previous code was inside the "pos" brackets, meaning that it was only entering if it was successfull. Since the error block could never get reached, I wasn't able to get the negative answer from the user.
Hope this was of use to anyone.
Related
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.
iOS issue only:
I am using the following code to get the users location.
navigator.geolocation.getCurrentPosition(
(position) => {
console.log("Native GEO GOOD", position);
return resolve(position)
},
(err) => {
console.log("Native GEO BADD", err);
return reject(err)
},
{ enableHighAccuracy: false, timeout: 5000, maximumAge: 0 },
)
The above code opens a dialog box, from which the user can allow my app to geolocate.
The problem is I want to wait until the user actually responds using the dialog box before calling the error or success callback.
I tried to use: requestAuthorization(). But that just opens the dialog box and I have no way to telling when the user has accepted the request to geolocate.
What I would like to do is ask the users permission to geolocate, then after the user accepts, try to geolocate the user.
But I don't see how to do that using react-native geolocation.
If requestAuthorization() took a callback option for when the user responds to the dialog box, that would solve my issue.
In React-Native using Expo (https://expo.io) you ask for permissions using a Promise and then act on the promise (hopefully when permission is given).
Permissions.askAsync((Permissions.LOCATION)
.then(({status}) => {
//your code here after permission is granted
});
);
If you aren't using expo, there is a Component call react-native-permissions (https://github.com/yonahforst/react-native-permissions.git) that allows you to request permissions using a promise like my example but without expo. Their example shows the request setting state to let you know the permissions status which you can act on.
Permissions.request('location', { type: 'always' }).then(response => {
this.setState({ locationPermission: response })
})
I am using React Native's Geolocation API to get user's location or ask user to turn location on:
// Handle PermissionsAndroid
this.watchID = navigator.geolocation.watchPosition(
(position) => {
// Update position
},
(error) => {
switch (error.code)
{
Case 1: {
// Ask user to turn on Location (Permission has already been asked for)
}
}
}
);
Now, I want to retry the watchPosition if user ever turned location on at some later point.
Using AppState, I tried getting an event if user started to interact with the notification bar (maybe user is trying to turn on Location). But it only calls back if application is sent to background or is activated again (but not during notification bar interactions).
Since Geolocation conforms with W3 standards, I tried searching for solutions in web development world. But the only solution that I found, was using iFrame which is browser-only.
Also, a non-elegant solution would be to setInterval (say every 5 seconds) and then clearInterval only if a position has been returned.
Is there a proper way to do this?
You should initiate the flow by getting the current location first, then create the watch. The following is from the Geolocation docs.
navigator.geolocation.getCurrentPosition(
(position) => {
if (position) {
//Handle first position
}
},
(error) => (console.log(error)),
{enableHighAccuracy: true, timeout: 20000, maximumAge: 1000}
);
this.watchID = navigator.geolocation.watchPosition((position) => {
if (position) {
// Handle new position
}
});
I've found this recovers from location errors itself, as well as handling permission requests (tested on iOS 10).
N.B. First time posting, so please don't hesitate to correct formatting errors, question form, etc.
I'm relatively new to react-native and but trying to build an app that makes changes to a google sheet using their API. I found a package to handle the OAuth authentication (repo-linked-here) but it seems to be throwing the following error:
TypeError: undefined is not an object (evaluating 'Module[fn]')
Here is most of my index.android.js:
...
import OAuthManager from 'react-native-oauth';
const manager = new OAuthManager('App');
export default class App extends Component {
constructor(props){
super(props);
this.state = {
isSignedIn: false
};
}
componentDidMount(){
manager.configure({
google: {
callback_url: 'http://localhost/google',
client_id: '*************',
client_secret: '************'
}
})
.then(resp => console.warn(resp))
.catch(err => console.warn(err));
}
...
React-native-oauth seems to indicate that if I use 'http://localhost/google' for the callback and add a few lines to the build.gradle file, then the callbacks/linking should work fine.
Any and all advice would be appreciated!
I think your are not calling authorize from manager. Also you can't add then & catch to configure:
componentDidMount(){
manager.configure({
google: {
callback_url: 'http://localhost/google',
client_id: '*************',
client_secret: '************'
}
});
manager.authorize('google', {scopes: 'profile email'})
.then(resp => console.warn(resp))
.catch(err => console.warn(err));
}
Maybe someone else had this problem .
I also had this error message and spend a lot of time to find any solution , and none of founded answers resolved my issue .
The problem was neither configure or authorise .
When you run (cd ios && pod install) and try to link it's asking you to overwrite pods file . Say YES .
I found it by running app from xcode , then get error message like :
framework not found DCTAuth
Then googling and found that it is related with pods file .
Hope this will help someone .
I really searched hard for it and I didn't find an answer. The problem I am facing is, that I programmed an application for an audiotour through a city based on open street map and the geolocation api.
So the problem I am facing is, that, if I access the application via G3 from my iphone I sometimes get a totaly inadequate location, (often the same, somewhere in the city), but if I use the google maps app I get an ecaxt position. I don't understand the fact, that if I make the same call from safari and from an app, I get different results.
I use 'navigator.geolocation.watchPosition' with the following options:
enableHighAccuracy: true,
timeout: 50000,
maximumAge: 0
I would really apreciate it, if someone who also faced the problem, and has an solution for this, would help me. What also happend is, that if I opend the web application and my iphone turns in power safe mode and I reactivate it, the position gets totally crazy.
My Code is really long and complicated, but maybe this helps:
options = {
enableHighAccuracy: true,
timeout: 50000,
maximumAge: 0
};
watchID = navigator.geolocation.getCurrentPosition( function(position) {
map.setCenter(lonLat, zoom );
}, function(error) { alert('Cannot determine your location! Check if you enabled geolocation for your browser.');}, options);
watchID = navigator.geolocation.watchPosition( function(position) { Here is the function!}
geolocationError,
{
enableHighAccuracy: true,
timeout: 50000,
maximumAge: 0
}
}
);