Location of the users logging in to the website via Geolocation and Javascript API, but violation errors - google-geolocation

Trying to access the locations of the users logging in to a website using Google's Geolocation and Javascript API. But it's giving me violation errors.
THE HTML File
<script>
var map, infoWindow;
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
center: {lat: -34.397, lng: 150.644},
zoom: 6
});
infoWindow = new google.maps.InfoWindow;
// Try HTML5 geolocation.
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
var pos = {
lat: position.coords.latitude,
lng: position.coords.longitude
};
infoWindow.setPosition(pos);
infoWindow.setContent('Location found.');
infoWindow.open(map);
map.setCenter(pos);
}, function() {
handleLocationError(true, infoWindow, map.getCenter());
});
} else {
// Browser doesn't support Geolocation
handleLocationError(false, infoWindow, map.getCenter());
}
}
function handleLocationError(browserHasGeolocation, infoWindow, pos) {
infoWindow.setPosition(pos);
infoWindow.setContent(browserHasGeolocation ?
'Error: The Geolocation service failed.' :
'Error: Your browser doesn\'t support geolocation.');
infoWindow.open(map);
}
</script>
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=MY_KEY&callback=initMap">
</script>
EXPRESSJS
const express=require('express');
const path = require('path');
const app=express();
app.get('/*', (req, res) => {
res.sendFile(path.join(__dirname, './geo.html'));
})
const port =8081;
app.listen(port,()=>{
console.log(`App running on ${port}`);
})
The Webpage is asking for my location and then throwing these following violation warnings:
[Violation] Only request geolocation information in response to a user gesture.
initMap # geo.html:20
(anonymous) # js?key=AIzaSyCZoELufy8fp9Vg4jGAAwAtDz0f8UJuxzc&callback=initMap:142
(anonymous) # js?key=AIzaSyCZoELufy8fp9Vg4jGAAwAtDz0f8UJuxzc&callback=initMap:142
util.js:45 [Violation] Added non-passive event listener to a scroll-blocking 'touchstart' event. Consider marking event handler as 'passive' to make the page more responsive. See https://www.chromestatus.com/feature/5745543795965952
(anonymous) # util.js:45
Nz # util.js:45
_.zE # util.js:134
LW # onion.js:30
(anonymous) # onion.js:35
util.js:45 [Violation] Added non-passive event listener to a scroll-blocking 'touchmove' event. Consider marking event handler as 'passive' to make the page more responsive. See https://www.chromestatus.com/feature/5745543795965952
can you help me solve this

Google has a recommendation that you don't ask for the users location on page load:
Users are mistrustful of or confused by pages that automatically request their location on page load. Rather than automatically requesting a user's location on page load, tie the request to a user's gesture, such as a tapping a "Find Stores Near Me" button. Make sure that the gesture clearly and explicitly expresses the need for the user's location.
You should add a button that gives some information to the user for why you need the location first, and then ask. This way users know why you need it.

Related

How to restrict API Key when calling the Reverse Geocoding API from Browser?

I am using Google Reverse Geocoding API from Browser.
The API works fine when using API Key with no restriction.
For example: https://maps.googleapis.com/maps/api/geocode/json?key=API_KEY_WITH_NO_RESTRICTION&latlng=41.8857156,-87.64823779999999 - OK
But as I am calling the API from the browser, I would like to restrict the API Key, preferably request originating from certain domains.
Now, as per the restriction guideline, HTTP Referer restrictions won't work for the Geocoding API (one of the Google Web Service API). It returns error "API keys with referer restrictions cannot be used with this API." in such case!
The other option is to use IP address restriction. But it seems to be more suited if the call was originating from the server. In that case server address could be added in the restriction.
How can I secure (restrict) the API Key if I want to continue to call the Geocoding API from the browser?
I figured out that I have to use Maps Javascript API in order to be able to call the Reverse Geocoding (Address Lookup) from browser (client) with HTTP Referer restrictions in place for the API Key.
In my initial implementation I used fetch(requestUrl) from the browser as it seemed very convenient and ended up with the above problem.
Example (using TypeScript):
Enable Maps Javascript API
Install required packages
npm install #googlemaps/js-api-loader
npm i -D #types/google.maps
reverseGeo.ts
import { Loader } from '#googlemaps/js-api-loader';
const loadScript = async (): Promise<void> => {
const loader = new Loader({
apiKey: API_KEY_WITH_REFERRER_RESTRICTION,
version: 'weekly',
});
await loader.load();
};
export async function reverseGeo(
lat: number, long: number
): Promise<string> {
await loadScript();
const geocoder = new google.maps.Geocoder();
const latlng = {
lat: lat,
lng: long,
};
try {
const { results } = await geocoder.geocode({ location: latlng });
if (results && results[0]) {
return results[0].formatted_address;
}
} catch (e) {
// handle exception
}
throw new TypeError('Zero result or reverse geo Failed'); // or handle other way
}
reverseGeo.spec.ts
import { reverseGeo} from './reverseGeo';
it('should test reverseGeo', async () => {
console.log(reverseGeo(22.5726, 88.3639));
});

Uncaught (in promise) DOMException When Initiating pushManager.subscribe

I'm trying to add push messaging to my service worker and facing issue that is eluding me since last night.
In my main HTML file, I have the following -
<script>
if('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('/service-worker.js', {scope: '/pwa/'}).then(registration => {
console.log('Service Worker Registered: ', registration);
registration.pushManager.subscribe({userVisibleOnly:true});
});
})
}
</script>
I do get "Service Worker Registered" message on the console. Which means the registration is successful. Chrome however follows it with following line that doesn't say anything about the error -
Uncaught (in promise) DOMException (index):1
Clicking on the (index):1 takes me to the top of corresponding page /pwa/, and highlights the <!DOCTYPE html>.
It does not give me any meaningful information to investigate the issue further.
Would appreciate if you could guide me in fixing this issue. I'll paste the rest of my code and setup below.
Backend framework: Laravel.
Entry in my webpack.mix.js
const workboxPlugin = require('workbox-webpack-plugin');
mix.webpackConfig({
plugins: [
new workboxPlugin.InjectManifest({
swSrc: 'public/service-worker-offline.js', // more control over the caching
swDest: 'service-worker.js', // the service-worker file name
importsDirectory: 'service-worker-assets' // have a dedicated folder for sw files
})
],
output: {
publicPath: '' // Refer: https://github.com/GoogleChrome/workbox/issues/1534
}
});
Entry in my service-worker-offline.js -
workbox.skipWaiting();
workbox.clientsClaim();
// some other entries, followed by
self.addEventListener('push', (event) => {
const title = 'Aha! Push Notifications with Service Worker';
const options = {
'body' : event.data.text()
};
event.waitUntil(self.registration.showNotification(title, options))
});
I look forward to your responses and thank you in advance for your help.
Addendum:
I did further investigation and found out that if I do -
Notification.requestPermission().then(function(permission) {
registration.pushManager.subscribe({userVisibleOnly: true});
})
then the push notification works; but the error still remains. However, the error now points to registration.pushManager.subscribe({userVisibleOnly: true}); line in the JS. What could be the reason?
The DOMException has details that are not always visible. Catch your DOMException, and make sure to log the message to the console. It will generally be much more informative. In my case, the "Registration failed - permission denied" message reminded me that I had blocked all notifications in my chrome settings.
If you are using react, fix serviceWorker.unregister () with serviceWorker.register () in index.js. I solved it like this

Detect if we gets new response from API

I am working on a React app.
I want to refresh my component details every time when it gets a new response from the API.
Can anyone please tell me, how can I detect if we get new response from API so that I could refresh my details.
Thank you !
You can use Stateful component and set the state to the data received from API. As reactJS uses Virtual DOM to check the changes made to the state, it will automatically get updated if there are any changes to the data received from your API request.
You can try something similar to this :
class App extends Component {
constructor(props){
super(props);
this.state= {
flats : []
};
}
componentDidMount(){
const url="example.com/api.json";
fetch(url)
.then(response => response.json())
.then(data => {
this.setState({
flats: data
});
})
}

Service worker causing CORS issues on Firefox

I'm using service worker for push notifications, following this article. Everything is working with Chrome but with Firefox (v.44.0.2) I have a weird issue.
On successful login to my app, I register the service worker which does nothing but waiting for push events; I see that is correctly registered (from some logging and from about:serviceworkers). Now, if I refresh the page (CTRL+R) all my POST have CORS issues (missing Access-Control-Allow-Origin header) due to this service worker and the user is redirected to login page; from here on all POSTs do not work for the same reason.
Conversely, if I login, unregister the service worker and then refresh, there are no problems at all. Any idea of what's going on? Again my service worker just handles push events, no caching no other processing done and it perfectly works on Chrome.
Here's my service worker code ( SOME_API_URL points to a real API which is not needed for testing purpose cause the issue happens after the service worker registers, no push events needed)
self.addEventListener('push', function(event) {
// Since there is no payload data with the first version
// of push messages, we'll grab some data from
// an API and use it to populate a notification
event.waitUntil(
fetch(SOME_API_URL).then(function(response) {
if (response.status !== 200) {
// Either show a message to the user explaining the error
// or enter a generic message and handle the
// onnotificationclick event to direct the user to a web page
console.log('Looks like there was a problem. Status Code: ' + response.status);
throw new Error();
}
// Examine the text in the response
return response.json().then(function(data) {
if (data.error || !data.notification) {
console.error('The API returned an error.', data.error);
throw new Error();
}
var title = data.notification.title;
var message = data.notification.message;
var icon = data.notification.icon;
var notificationTag = data.notification.tag;
return self.registration.showNotification(title, {
body: message,
icon: icon,
tag: notificationTag
});
});
}).catch(function(err) {
console.error('Unable to retrieve data', err);
var title = 'An error occurred';
var message = 'We were unable to get the information for this push message';
var notificationTag = 'notification-error';
return self.registration.showNotification(title, {
body: message,
tag: notificationTag
});
})
);
});
self.addEventListener('notificationclick', function(event) {
console.log('On notification click: ', event.notification.tag);
// Android doesn't close the notification when you click on it
// See: http://crbug.com/463146
event.notification.close();
// This looks to see if the current is already open and
// focuses if it is
event.waitUntil(
clients.matchAll({
type: 'window'
})
.then(function(clientList) {
for (var i = 0; i < clientList.length; i++) {
var client = clientList[i];
if (client.url == '/' && 'focus' in client)
return client.focus();
}
if (clients.openWindow) {
return clients.openWindow('/');
}
})
);
});
Firefox 44 has bug 1243453, which causes the Origin header of cross-origin requests to get dropped if the service worker doesn't listen for fetch events.
The bug has been fixed in Firefox 45, which will be released the week of March 8, 2016 (next week, as of the time of this writing). In the meantime, and for users who don't immediately upgrade to the latest Firefox release, you can work around the problem by adding this code to the service worker:
addEventListener('fetch', function(evt) {
evt.respondWith(fetch(evt.request));
});

YouTube Data API: add a subscription

I'm using YouTube's V3 Data API to add a subscription to a channel. This occurs on a Wordpress installation.
I added Google APIs (for oauth) on Wordpress theme functions:
wp_enqueue_script( 'googleapi', 'https://apis.google.com/js/client.js?onload=googleApiClientReady', array(), '1.0.0', true );
I added in the same way the oauth javascript file, which is the first one here: https://developers.google.com/youtube/v3/code_samples/javascript.
Following this guide(https://developers.google.com/youtube/v3/docs/subscriptions/insert (Apps Script)), I extended the OAuth js with the addSubscription method.
Google Client API seems to be loaded and working as it calls correctly googleApiClientReady on the oauth javascript.
So, this is how the subscription is being inserted:
OAUTH JAVASCRIPT
... ... ...
// After the API loads
function handleAPILoaded() {
addSubscription();
}
function addSubscription() {
// Replace this channel ID with the channel ID you want to subscribe to
var channelId = 'this is filled with the channel ID';
var resource = {
snippet: {
resourceId: {
kind: 'youtube#channel',
channelId: channelId
}
}
};
try {
var response = YouTube.Subscriptions.insert(resource, 'snippet');
jQuery('#success').show();
} catch (e) {
if(e.message.match('subscriptionDuplicate')) {
jQuery('#success').show();
} else {
jQuery('#fail').show();
alert("Please send us a mail () with the following: ERROR: " + e.message);
}
}
So, the first error comes with
YouTube.Subscriptions.insert(resource, 'snippet')
It says YouTube is not defined. I replaced it with:
gapi.client.youtube.subscriptions.insert(resource, 'snippet');
And that error went away. When checking response, as the subscription isn't completed, this is what I get
{"wc":1,"hg":{"Ph":null,"hg":{"path":"/youtube/v3/subscriptions","method":"POST","params":{},"headers":{},"body":"snippet","root":"https://www.googleapis.com"},"wc":"auto"}}
So, I would like to know what's happening on that POST request and what's the solution to this.
I can post the full OAuth file, but it's just as in the example, plus that addSubscription method at the end.
Okay, I got it working, the problem was on the POST request. Here is the full method working:
// Subscribes the authorized user to the channel specified
function addSubscription(channelSub) {
var resource = {
part: 'id,snippet',
snippet: {
resourceId: {
kind: 'youtube#channel',
channelId: channelSub
}
}
};
var request = gapi.client.youtube.subscriptions.insert(resource);
request.execute(function (response) {
var result = response.result;
if (result) {
// alert("Subscription completed");
}
} else {
// alert("Subscripion failed");
// ...
}
});
}
Also make sure to load Google Apps API (in fact without it the authorize/login button won't work) and jQuery.
Any chance you can post everything that made this work...all the JS entire auth.js save for your private keys, im working on this exact problem.

Resources