首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用Firebase管理sdk和云函数时出现FCM错误

使用Firebase管理sdk和云函数时出现FCM错误
EN

Stack Overflow用户
提问于 2017-07-10 13:50:18
回答 3查看 3K关注 0票数 4

反复得到这个错误。Error#1

代码语言:javascript
运行
复制
    { Error: fcm.googleapis.com network timeout. Please try again.
    at FirebaseAppError.Error (native)
    at FirebaseAppError.FirebaseError [as constructor] (/user_code/node_modules/firebase-admin/lib/utils/error.js:25:28)
    at new FirebaseAppError (/user_code/node_modules/firebase-admin/lib/utils/error.js:70:23)
    at TLSSocket.<anonymous> (/user_code/node_modules/firebase-admin/lib/utils/api-request.js:106:51)
    at emitNone (events.js:86:13)
    at TLSSocket.emit (events.js:185:7)
    at TLSSocket.Socket._onTimeout (net.js:339:8)
    at ontimeout (timers.js:365:14)
    at tryOnTimeout (timers.js:237:5)
    at Timer.listOnTimeout (timers.js:207:5)
  errorInfo: 
   { code: 'app/network-timeout',
     message: 'fcm.googleapis.com network timeout. Please try again.' } }

我有时也会遇到另一个错误。错误#2

代码语言:javascript
运行
复制
 { Error: Credential implementation provided to initializeApp() via the "credential" property failed to fetch a valid Google OAuth2 access token with the following error: "read ECONNRESET".
    at FirebaseAppError.Error (native)
    at FirebaseAppError.FirebaseError [as constructor] (/user_code/node_modules/firebase-admin/lib/utils/error.js:25:28)
    at new FirebaseAppError (/user_code/node_modules/firebase-admin/lib/utils/error.js:70:23)
    at /user_code/node_modules/firebase-admin/lib/firebase-app.js:106:23
    at process._tickDomainCallback (internal/process/next_tick.js:129:7)
  errorInfo: 
   { code: 'app/invalid-credential',
     message: 'Credential implementation provided to initializeApp() via the "credential" property failed to fetch a valid Google OAuth2 access token with the following error: "read ECONNRESET".' } }

还有一种类型。错误#3

代码语言:javascript
运行
复制
Error sending message: { Error: A network request error has occurred: read ECONNRESET
    at FirebaseAppError.Error (native)
    at FirebaseAppError.FirebaseError [as constructor] (/user_code/node_modules/firebase-admin/lib/utils/error.js:25:28)
    at new FirebaseAppError (/user_code/node_modules/firebase-admin/lib/utils/error.js:70:23)
    at ClientRequest.<anonymous> (/user_code/node_modules/firebase-admin/lib/utils/api-request.js:115:43)
    at emitOne (events.js:96:13)
    at ClientRequest.emit (events.js:188:7)
    at TLSSocket.socketErrorListener (_http_client.js:310:9)
    at emitOne (events.js:96:13)
    at TLSSocket.emit (events.js:188:7)
    at emitErrorNT (net.js:1276:8)
  errorInfo: 
   { code: 'app/network-error',
     message: 'A network request error has occurred: read ECONNRESET' } }

我尝试对我的云功能做的是根据价格匹配发送FCM消息来检查用户的详细信息。云函数是数据库触发器。这是我的云函数的代码。我在代码中看不到任何问题,因为我正在使用promises。

代码语言:javascript
运行
复制
// Checks price alerts for users
exports.priceAlertCheck = functions.database.ref('/crons/alerts/price').onWrite(event => {
  const promises = [];
  admin.database().ref(`/alerts/price`).once('value', function(alertSnapshot) {
    alertSnapshot.forEach(function(dataSnapshot) {
      promises.push(createPriceAlertPromise(dataSnapshot));
    });
  });
  return Promise.all(promises);
});

function createPriceUrl(fromCurrency, toCurrency, exchange) {
  return 'https://zzzz.com/data/price?fsym='
          +fromCurrency+'&tsyms='+toCurrency+(exchange ? '&e='+exchange : '');
}

function createPriceAlertPromise(snapshot) {
  const comboKeyArray = snapshot.key.split('-');
  const fromCurrency = comboKeyArray[0];
  const toCurrency = comboKeyArray[1];
  const exchange = comboKeyArray[2];
  return request(createPriceUrl(fromCurrency, toCurrency, exchange), function (error, response, body) {
      if (!error && response.statusCode == 200) {
        const jsonobj = JSON.parse(response.body);
        const currentPrice = jsonobj[toCurrency];
        const promises = [];

        snapshot.forEach(function(data) {
            promises.push(sendAlertNotifications(snapshot.key, data.key, currentPrice));
        });
        return Promise.all(promises);
      } else {
        console.log('Error fetching price', snapshot.key);
      }
  });
}

function sendAlertNotifications(comboKey, userId, currentPrice) {
  const getUserPromise = admin.database()
                          .ref(`/users/${userId}`)
                          .once('value');
  const getUserPriceAlertsPromise = admin.database()
                          .ref(`/user_alerts/price/${userId}`)
                          .once('value');
  return Promise.all([getUserPromise, getUserPriceAlertsPromise]).then(results => {
    const userSnapshot = results[0];
    if(!userSnapshot.val()){
      return console.log('Not user details', userId)
    }
    const instanceId = userSnapshot.val().instanceId;
    const subscriptionStatus = userSnapshot.val().subscriptionStatus;
    const priceAlertSnapshot = results[1];
    if(subscriptionStatus != 1){
      return console.log('Not Sending alerts. Subscription Expired', userId);
    }
    // Check if there are any device tokens.
    if (!priceAlertSnapshot.hasChildren()) {
      return console.log('There are no alerts to send for', comboKey, ", userId:", userId);
    }
    console.log("Alerts of users fetched for ", comboKey, " : ", priceAlertSnapshot.numChildren(), ", userId:", userId);
    const promises = [];
    priceAlertSnapshot.forEach(function(dataSnapshot) {
        promises.push(sendAlertNotification(userId, instanceId, currentPrice, dataSnapshot));
    });
    return Promise.all(promises);
  })
  .catch(error => {
    console.log("Error getting user alert details:", error, ", userId:", userId);
  });
}

function sendAlertNotification(userId, instanceId, currentPrice, dataSnapshot) {
  const comboKey = dataSnapshot.val().name;
  const comboKeyArray = comboKey.split('-');
  const fromCurrency = comboKeyArray[0];
  const toCurrency = comboKeyArray[1];
  const exchange = comboKeyArray[2];
  const alertPrice = dataSnapshot.val().value;
  if(priceAlertConditionCheck(currentPrice, dataSnapshot)) {
    // Notification details.
    const payload = {
      notification: {
        title: `${fromCurrency} Price Alert`,
        body: "You have been notified",
        sound: 'default',
        tag: comboKey
      },
      data: {
        title: `${fromCurrency} Price Alert`,
        body: "You have been notified",
        name: comboKey,
        sound: 'default',
        type: "alert"
      }
    };
    // Set the message as high priority and have it expire after 24 hours.
    var options = {
      priority: "high",
      timeToLive: 60 * 10
    };

    return admin.messaging().sendToDevice(instanceId, payload, options).then(response => {
      response.results.forEach((result, index) => {
        const error = result.error;
        if (error) {
          console.error("Failure sending message:", error, " userId:", userId, " token:", instanceId);
        }
        console.log("Successfully sent message:", response, ", userId:", userId);
      });
    })
    .catch(error => {
      console.log("Error sending message:", error, " userId:", userId, " token:", instanceId);
    });
  }
  return;
}

目前数据很小,但我在firebase数据库中仍然得到了30%的失败(10到15条记录)。当有10k条记录时,这是如何工作的?如何防止这些错误?此外,没有这些错误代码'app/‘的文档,只有'message/’错误的文档。

UPDATE#1 :更新函数:

代码语言:javascript
运行
复制
function createPriceAlertPromise(snapshot) {
  const comboKeyArray = snapshot.key.split('-');
  const fromCurrency = comboKeyArray[0];
  const toCurrency = comboKeyArray[1];
  const exchange = comboKeyArray[2];
  return rp(createPriceUrl(fromCurrency, toCurrency, exchange),
  {resolveWithFullResponse: true}).then(response => {
    if (response.statusCode === 200) {
      const jsonobj = JSON.parse(response.body);
      const currentPrice = jsonobj[toCurrency];
      const promises = [];

      snapshot.forEach(function(data) {
          promises.push(sendAlertNotifications(snapshot.key, data.key, currentPrice));
      });
      return Promise.all(promises);
    }
    throw response.body;
  }).catch(error => {
    console.log('Error fetching price', error);
  });
}

UPDATE#2 :将函数的超时时间增加到540秒,但仍然获得error#1

UPDATE#3 :更新的功能: Error#1现在消失了,但error#3仍然存在,并且发生得更频繁

代码语言:javascript
运行
复制
// Checks price alerts for users
exports.priceAlertCheck = functions.database.ref('/crons/alerts/price').onWrite(event => {
  return admin.database().ref(`/alerts/price`).once('value').then(alertSnapshot => {
    const promises = [];
    alertSnapshot.forEach(function(dataSnapshot) {
      promises.push(createPriceAlertPromise(dataSnapshot));
    });
    return Promise.all(promises).then(response => {
      return deleteFirebaseApp();
    })
    .catch(function(error) {
      return logError(error);
    });
  });
});
function createPriceAlertPromise(snapshot) {
  const comboKeyArray = snapshot.key.split('-');
  const fromCurrency = comboKeyArray[0];
  const toCurrency = comboKeyArray[1];
  const exchange = comboKeyArray[2];
  return rp(createPriceUrl(fromCurrency, toCurrency, exchange),
  {resolveWithFullResponse: true}).then(response => {
    if (response.statusCode === 200) {
      const jsonobj = JSON.parse(response.body);
      const currentPrice = jsonobj[toCurrency];

      const forEachPromise =  new Promise(function(resolve) {
        const promises = [];
        snapshot.forEach(function(data) {
          promises.push(sendAlertNotifications(snapshot.key, data.key, currentPrice));
        });
        resolve(promises);
      });

      forEachPromise.then(promises => {
        return Promise.all(promises);
      })
      .catch(error => {
        return reportError(error, { type: 'database_query', context: 'forEach'});
      });
    } else {
      throw response.body;
    }
  }).catch(error => {
    return reportError(error, { type: 'http_request', context: 'price fetching'});
  });
}
EN

Stack Overflow用户

发布于 2017-08-04 06:20:49

第494行: response.results.forEach((result,index) => {

应修改为:

返回结果(response.results.map((result,RSVP.all) => {

"forEach“返回null,这意味着promise实际上立即解析为null。"map“返回一个数组,RSVP.all确保数组中的所有promises都被解析。

目前,函数在所有异步任务完成之前就被终止了,这就是为什么你会得到这个错误。

票数 0
EN
查看全部 3 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45004564

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档