PWA beforeinstallprompt Uncaught (в промисе) DOMException

Приведенная ниже функция отлично работает, когда пользователь устанавливает пакет pwa. Однако если они откажутся, то при следующем посещении сайта deferredPrompt.prompt(); выдаст исключение Uncaught (in promise) DOMException, даже если deferredPrompt.prompt(); не определено.

Есть ли что-то, что мне нужно проверить в отношении ранее данного ответа пользователей?

window.addEventListener('beforeinstallprompt', (e) => {
    // Prevent Chrome 67 and earlier from automatically showing the prompt
    //e.preventDefault();

    let deferredPrompt;

    // Stash the event so it can be triggered later.
    deferredPrompt = e;
    // Show the prompt
    deferredPrompt.prompt();
    // Wait for the user to respond to the prompt
    deferredPrompt.userChoice
    .then((choiceResult) => {
      if (choiceResult.outcome === 'accepted') {
        console.log('User accepted the A2HS prompt');
      } else {
        console.log('User dismissed the A2HS prompt');
      }
      deferredPrompt = null;
    });
});

person rory    schedule 21.05.2019    source источник
comment
Такая же ошибка, вы ее решили? Я скопировал фрагмент прямо из конструктора PWA.   -  person Madeo    schedule 14.06.2019
comment
@Мадео, к сожалению, нет. Если я когда-нибудь это сделаю, я вернусь сюда и опубликую ответ   -  person rory    schedule 17.06.2019
comment
У меня такая же проблема. Пока нет решений?   -  person Adriel Werlich    schedule 23.07.2019


Ответы (2)


У меня есть аналогичный код и я сталкиваюсь с той же проблемой. После некоторых исследований я понимаю, что deferredPrompt.prompt() вернет userResponsePromise, что является обещанием. Затем я пытаюсь увидеть, что происходит, добавляя эту строку кода для наблюдения за журналом.

deferredPrompt.prompt()
  .then(res => console.log(res))
  .catch(error => { console.log(`----> ${error}`) })

в журнале консоли это показывает

----> NotAllowedError: The prompt() method must be called with a user gesture

Я предполагаю, что процесс установки A2HS может не разрешить прямой вызов prompt(). Поэтому я пытаюсь изменить свой код, настроив кнопку призыва к действию, которая вызовет метод prompt(), который, я полагаю, должен подразумевать значение «жеста пользователя», как предполагает журнал.

Вот мой новый код, который похож на код из руководства по Добавить на главный экран. от Google dev. (не знаю, почему я не следил за ним в первый раз :P)

window.addEventListener('beforeinstallprompt', e => {
  e.preventDefault()
  deferredPrompt = e
})

const btnInstallApp = document.getElementById('btn-install-app')

if(btnInstallApp) {
  btnInstallApp.addEventListener('click', e => {
    deferredPrompt.prompt()
    deferredPrompt.userChoice
      .then(choiceResult => {
        if(choiceResult.outcome === 'accepted') {
          console.log('user accepted A2HS prompt')
        } else {
          console.log('user dismissed A2HS prompt')
        }
        deferredPrompt = null
      })
    })
}

Я добавляю кнопку «Установить приложение» где-нибудь на странице

<button id="btn-install-app" class="btn">Install App</button>

На этот раз я вижу приглашение «Добавить на главный экран» после нажатия кнопки «Установить приложение». Я надеюсь, что это поможет.

person worrawut    schedule 05.08.2019
comment
Я получал сообщение об ошибке при попытке активировать A2HS из события mousedown библиотеки холстов CreateJS/ZIMjs. Как только я наложил кнопку HTML, ошибка исчезла. Так что... очень жаль, что система не распознает события холста как обычный жест. - person Dan Zen; 27.08.2019

Будь осторожен!

Мой код pwa похож и работал нормально. Однако внезапно после тривиального изменения кода я получил эту ошибку в режиме отладки с помощью инструментов разработчика Chrome.

Я заметил, что установил точку останова непосредственно перед deferredPromt.prompt(). Это вызвало ошибку, потому что прослушиватель устанавливает таймер, чтобы определить, было ли событие связано с жестом пользователя.

Сбросив точку останова, мой код снова заработал.

person calterras    schedule 12.06.2020