admin管理员组

文章数量:1404464

I am trying to use the Permissions API: Which should be supported by Firefox. (I am currently using Firefox Developer Edition 66.0b14).

I have a page where I initially check user permissions. Something like;

if (navigator.permissions) {
  navigator.permissions.query({ name: 'geolocation' }).then(result => {
    if (result.state === 'granted') {
      this.getCurrentPosition()
    } else if (result.state === 'prompt') {
      this.getCurrentPosition()
      console.log('Permissions requested. Waiting for user input...')
    } else if (result.state === 'denied') {
      this.locationError = true
    }
    result.onchange = event => {
      if (event.target.state === 'granted') {
        this.locationError = false
        this.getCurrentPosition()
        console.log('Thanks for letting us know...')
      } else if (event.target.state === 'denied') {
        this.locationError = true
      }
    }
  })
}

Now this works all fine in Chrome for example. (Btw: I use this.locationError to show some info window saying that the app will only work with location services enabled)

Anyway, if I open it in Firefox I get the prompt as expected: Now If I check the box «Remember this decision» and send either Allow/Block, I see that the onchange is executed as expected, giving me the possibility to react onto the users decision.

BUT, if I don't check this box, and just deny or allow once, the onchange is not called, leaving me in the unknown of what actually happened. Also this the state remains being 'prompt'.

I also tried to set an interval to check Permissions again after some time, but again it would just open the prompt asking for the permission. The state never updates or changes from 'prompt' to 'denied' or 'granted'.

Is there something I am missing, or is this a Firefox bug.

Thanks for any hints

Cheers

I am trying to use the Permissions API: https://developer.mozilla/en-US/docs/Web/API/Permissions/query Which should be supported by Firefox. (I am currently using Firefox Developer Edition 66.0b14).

I have a page where I initially check user permissions. Something like;

if (navigator.permissions) {
  navigator.permissions.query({ name: 'geolocation' }).then(result => {
    if (result.state === 'granted') {
      this.getCurrentPosition()
    } else if (result.state === 'prompt') {
      this.getCurrentPosition()
      console.log('Permissions requested. Waiting for user input...')
    } else if (result.state === 'denied') {
      this.locationError = true
    }
    result.onchange = event => {
      if (event.target.state === 'granted') {
        this.locationError = false
        this.getCurrentPosition()
        console.log('Thanks for letting us know...')
      } else if (event.target.state === 'denied') {
        this.locationError = true
      }
    }
  })
}

Now this works all fine in Chrome for example. (Btw: I use this.locationError to show some info window saying that the app will only work with location services enabled)

Anyway, if I open it in Firefox I get the prompt as expected: Now If I check the box «Remember this decision» and send either Allow/Block, I see that the onchange is executed as expected, giving me the possibility to react onto the users decision.

BUT, if I don't check this box, and just deny or allow once, the onchange is not called, leaving me in the unknown of what actually happened. Also this the state remains being 'prompt'.

I also tried to set an interval to check Permissions again after some time, but again it would just open the prompt asking for the permission. The state never updates or changes from 'prompt' to 'denied' or 'granted'.

Is there something I am missing, or is this a Firefox bug.

Thanks for any hints

Cheers

Share Improve this question asked Mar 12, 2019 at 17:05 MercMerc 4,5808 gold badges58 silver badges87 bronze badges 4
  • 1 I'm running into this as well. Seems kinda weird, because if you deny and you don't check the remember box, even though the permissionstatus.state still says prompt, the fact that the user denied it seems to be remembered. This seems WAY opposite of intuitive: if there is a checkbox for remembering an end-users choice, and that end-user doesn't check that box, the fact that that choice is REMEMBERED just doesn't make sense... – Jake Smith Commented Sep 10, 2020 at 17:37
  • @JakeSmith but it should be remembered for that session atleast right? – ɹɐqʞɐ zoɹǝɟ Commented Apr 26, 2021 at 5:53
  • I don't see why that is an assumption I should make. But I have no clue. If a user doesn't say remember, then remember it should not would be my assumption. The app shouldn't incessantly ask the user for permission, but I don't see how the user is able to change their mind if the app isn't allowed to ask for permission again. – Jake Smith Commented May 12, 2021 at 1:52
  • 1 For anyone having the same issue, it's a bug in Firefox: bugzilla.mozilla/show_bug.cgi?id=1754372 – Darek Kay Commented Apr 24, 2023 at 13:09
Add a ment  | 

1 Answer 1

Reset to default 2

I was unable to get the onchange function or change event to work for Firefox but was able to find a workaround that worked just as well to identify a change in permission:

Note: this fix will only work if you are using geolocation.getCurrentPosition

  navigator.permissions.query({
    name: 'geolocation'
  }).then(function(result) {
      
    const onLocationFetchSuccess = (position) => {
      /*
         Consume location coordinates here and proceed as required
         using position.coords.latitude and position.coords.longitude
      */
    };

    const onLocationFetchFailure = (error = {}) => {
      // Error code 1 corresponds to user denying/blocking the location permission
      if (error.code === 1) {
        // Respond to failure case as required
      }
    };

    navigator.geolocation.getCurrentPosition(onLocationFetchSuccess, onLocationFetchFailure);

    if (result.state === 'denied') {
      onLocationFetchFailure();
    }

    // This will still work for Chrome
    result.onchange = function() {
      if (result.state === 'denied') {
        onLocationFetchFailure();
      }
    }
  })

This solution will trigger the failure case twice for Chrome browsers. To avoid that one can check for current browser to conditionally prevent sending the onLocationFetchFalure callback to getCurrentPosition for Chrome browsers.

TLDR; the fix here is that instead of relying on the change event / onchange function to be triggered, we pass an error callback to getCurrentPosition which is triggered when the location permission is changed through the permission dialog. This error callback provides an error code of 1 when the user denies/blocks the location permission.

本文标签: javascriptNavigatorpermissionsquery Geolocation onChange not working in FirefoxStack Overflow