Функции Firebase не могут отправить некоторые push-уведомления с помощью асинхронного метода sendMulticast - PullRequest
0 голосов
/ 13 апреля 2019

Из-за этого меня несколько дней ставили в тупик.Там много кода, поэтому я надеюсь, что вы можете остаться со мной ..

Я собрал весь код, который вы видите ниже, в одном месте, чтобы сделать его проще:

https://stackblitz.com/edit/angular-us7xwt

Хорошо, давайте начнем!

Я запускаю ежедневное задание cron, чтобы уведомлять пользователей, когда у них появляется новая музыка, для проверки того, какой из них запускает функцию firebase.Чтобы запросить выпуски, мой веб-сайт API возвращает массив объектов пользователей и исполнителей, для которых они выпускают музыку, которые выпускают музыку сегодня:

Вызов API, который запускается после запуска функции firebase

axios.get(`${apiURL}...`).then((response) => {
    var users = response.data;
    if(users.length > 0) {
        createTopics(users)
    }
})

Данные, возвращаемые этим вызовом API, отформатированы таким образом и хранятся в переменной users выше.Если массив заполнен, я запускаю createTopics(users)

  [{
    "userUID": "kaLOIkGwrWO4DSFP41OmfozxhsN2",
    "artists": [
      "Adventure Club",
      "LSD",
      "Marshmello"
    ]
  },
  {
    "userUID": "ZvOBNBqxbgRYoibSYEwkL9YKtWG2",
    "artists": [
      "Krewella",
      "Lolo Zouaï",
      "The Chemical Brothers"
    ]
  }]

createTopics ()

. Здесь создаются метаданные для push-уведомлений для каждого пользователя.После создания сообщения мне нужно запросить все устройства, которыми владеет конкретный пользователь, чтобы я мог отправлять уведомления всем из них, используя Firebase multicast()

function createTopics(users) {

    users.forEach((user: any) => {

        const message = {
            notification: {
                title: `my title`,
                body: `my body`
            },
            tokens: null
        }
        // tslint:disable-next-line:no-floating-promises
        findUserDevices(user.userUID, message);
    })
}

findUserDevices ()

Эта функция запрашивает в моей базе данных пожарного хранилища токены устройства конкретного пользователя, необходимые для отправки push-уведомления.Если в нашей базе данных для этого пользователя есть устройства, нам нужно отправить сообщение на их устройства.

function findUserDevices(uid: string, message) {
    collectionData(fb.firestore().collection('devices').where('userId', '==', uid)).pipe(
        filter((userDevices) => userDevices && userDevices.length > 0),
        take(1)
    ).subscribe((devices: any) => {
        var userDeviceTokens: string[] = devices.map((device: any) => device.token);
        console.log(userDeviceTokens)
        if (userDeviceTokens !== undefined && userDeviceTokens.length != 0) {
            // tslint:disable-next-line:no-floating-promises
            pushToDevices(userDeviceTokens, message);
        }
    })
}

pushToDevices ()

Ниже приводится асинхронная функция.для отправки сообщений на устройства ... может быть, это где-то не так ??Я прикрепляю токены к payload, затем использую sendMulticast().В ответ на этот метод, если какие-либо токены не работают, я удаляю их с помощью асинхронного вызова deleteOldToken().

async function pushToDevices(userDeviceTokens, payload) {
    payload['tokens'] = userDeviceTokens;
    await admin.messaging().sendMulticast(payload).then((response) => {
        console.log('Success:', response);
        if (response.failureCount > 0) {
            const failedTokens = [];
            response.responses.forEach((resp, idx) => {
                if (!resp.success) {
                    failedTokens.push(userDeviceTokens[idx]);
                }
            });
            failedTokens.forEach((token) => {
                var tokenInstanceID = token.split(':')[0];
                // tslint:disable-next-line:no-floating-promises
                deleteOldToken(tokenInstanceID);
            })
          }
    })
        .catch((error) => {
            console.log('Error:', error)
    });
}

deleteOldToken ()

async function deleteOldToken(tokenInstanceID) {
    await fb.firestore().collection('devices').doc(tokenInstanceID).delete().then(() => {
        console.log(`Token ${tokenInstanceID} deleted`)
    })
}

Вот и весь метод, вот мои журналы

Lookingв журналах консоли я вижу смесь странной активности с несколькими строками ошибок тайм-аута

Error: { Error: Error while making request: timeout of 10000ms exceeded.
    at FirebaseAppError.Error (native)
    at FirebaseAppError.FirebaseError [as constructor] (/user_code/node_modules/firebase-admin/lib/utils/error.js:42:28)
    at FirebaseAppError.PrefixedFirebaseError [as constructor] (/user_code/node_modules/firebase-admin/lib/utils/error.js:88:28)
    at new FirebaseAppError (/user_code/node_modules/firebase-admin/lib/utils/error.js:122:28)
    at /user_code/node_modules/firebase-admin/lib/utils/api-request.js:152:23
    at process._tickDomainCallback (internal/process/next_tick.js:135:7)
  errorInfo: 
   { code: 'app/network-timeout',
     message: 'Error while making request: timeout of 10000ms exceeded.' },
  codePrefix: 'app' }

и несколькими строками ошибок сброса соединения:

Error: { Error: Error while making request: read ECONNRESET. Error code: ECONNRESET
    at FirebaseAppError.Error (native)
    at FirebaseAppError.FirebaseError [as constructor] (/user_code/node_modules/firebase-admin/lib/utils/error.js:42:28)
    at FirebaseAppError.PrefixedFirebaseError [as constructor] (/user_code/node_modules/firebase-admin/lib/utils/error.js:88:28)
    at new FirebaseAppError (/user_code/node_modules/firebase-admin/lib/utils/error.js:122:28)
    at /user_code/node_modules/firebase-admin/lib/utils/api-request.js:154:19
    at process._tickDomainCallback (internal/process/next_tick.js:135:7)
  errorInfo: 
   { code: 'app/network-error',
     message: 'Error while making request: read ECONNRESET. Error code: ECONNRESET' },
  codePrefix: 'app' }

И, наконец, некоторыеотлично работают:

Success: { responses: 
   [ { success: true,
       messageId: 'projects/release-hub-f3f5f/messages/1555102845415084' },
     { success: true,
       messageId: 'projects/release-hub-f3f5f/messages/0:1555102845414983%f95cf250f95cf250' } ],
  successCount: 2,
  failureCount: 0 }

После контакта с некоторыми из моих пользователей, некоторые получили свои push-уведомления, а многие нет.У меня есть догадка, что это связано с моими асинхронными вызовами, но где я иду не так?Большое спасибо за то, что остались с этим вопросом, пожалуйста, дайте мне знать, если вам нужна дополнительная информация.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...