繁体   English   中英

Firebase 管理员 SDK 身份验证错误“TOO_MANY_ATTEMPTS_TRY_LATER”

[英]Firebase Admin SDK Auth error "TOO_MANY_ATTEMPTS_TRY_LATER"

我在我的云功能中使用 firebase admin sdk 并且在尝试通过 uid 获取用户时在某些执行中随机出现错误。

let userRecord = await admin.auth().getUser(userId);

错误详情如下:

{"error":{"code":400,"message":"TOO_MANY_ATTEMPTS_TRY_LATER",
 "errors":[{ "message":"TOO_MANY_ATTEMPTS_TRY_LATER",
             "domain":"global","reason":"invalid"}]
 }
}

我的云 function 在实时数据库write时执行,并且可以为多个用户触发。 在一次执行中,我总共有 4 个 auth function 调用,第一个调用是上述调用,第二个调用是通过uidemail再次获取用户,第三个调用是generateEmailVerificationLink ,最后一个调用是generatePasswordResetLink

我已经检查了 auth 文档中的速率限制,但没有提到这些操作的速率限制。 此外,错误TOO_MANY_ATTEMPTS_TRY_LATER仅在 REST API 中提到,用于注册 email 密码。

如果此错误是由于速率限制引起的,鉴于这 4 个调用对于数据库写入所需的操作是必需的,我应该更改什么来防止此错误?。

编辑:

我已经确定了引发太多尝试错误的实际调用。 调用auth().generateEmailVerificationLink()auth().generatePasswordResetLink()调用次数过多时会引发此错误。

我用 100 次迭代循环调用这两个并等待承诺。 第一次执行完成时没有任何错误,即 200 个请求。 但是一旦第一次结束就开始第二次执行会抛出尝试次数过多的错误。 所以我认为这两个电话有限制。 现在我正在尝试减少这些调用并重用链接信息。 getUserByEmail等其他调用工作正常。

let promises = [];
let auth = admin.auth();
let hrstart = process.hrtime()
for (let i = 0; i < 100; i++) {
    promises.push(auth.getUserByEmail("user email"));
    promises.push(auth.generateEmailVerificationLink("user email", {url: `https://app.firebaseapp.com/path`}));
    promises.push(auth.generatePasswordResetLink("user email", {url: `https://app.firebaseapp.com/path`}));

}

Promise.all(promises)
    .then(value => {
        let hrend = process.hrtime(hrstart);
        console.log(hrend);
        // console.log(value)
    });

该错误特别出现在auth.createEmailLink操作中。 此功能有以下限制: 20QPS/IP 地址,其中 QPS 为(每秒查询)。 可以通过将用例提交给 Firebase 来增加此限制。

提交我的问题后,我从 firebase 支持部门获得了此信息。

链接到我的 github 问题: https : //github.com/firebase/firebase-admin-node/issues/458

我的速度低于 20QPS,但收到此异常。 事实上,它总是会在第二次尝试时抛出TOO_MANY_ATTEMPTS_TRY_LATER异常。

原来是使用FirebaseAuth.DefaultInstance而不是这样实例化静态实例:

在类定义中: private readonly FirebaseApp _firebase;

在类构造函数中: _firebase = FirebaseAdmin.FirebaseApp.Create();

在功能上:

var auth = FirebaseAuth.GetAuth(_firebase);
var actionCodeSettings = new ActionCodeSettings()
{
    ...
};
var link = await auth.GenerateEmailVerificationLinkAsync(email, actionCodeSettings);
return link;

除了https://stackoverflow.com/a/54782967/5515861中提到的答案之外,如果您在尝试创建自定义 email 验证时发现此问题,我想添加另一个解决方案。

受此 GitHub 问题 https://github.com/firebase/firebase-admin-node/issues/458#issuecomment-933161448中的响应的启发。

我也看到了这个问题。 我没有在 24 小时内(从其他任何地方或任何用户)运行 admin.auth().generateEmailVerificationLink 并且现在只调用了一次(在 prod 函数环境中部署时)并得到了这个 400 TOO_MANY_ATTEMPTS_TRY_LATER 错误......但是,客户端也确实在同一时间(显然不同的 IP)调用了 Firebase.auth.currentUser.sendEmailVerification() 方法。 这可能是问题吗?

我对这个问题的解决方案是添加重试。 例如

exports.sendWelcomeEmail = functions.runWith({failurePolicy: true}).auth.user().onCreate(async (user) => {
    functions.logger.log("Running email...");
    const email = user.email;
    const displayName = user.displayName;
    const link = await auth.generateEmailVerificationLink(email, {
      url: 'https://mpj.io',
    });

    await sendWelcomeEmail(email, displayName, link);
});

.runWith({failurePolicy: true})是关键。

它给您一个错误,因为您的云功能/后端调用generateEmailVerificationLink而同时 Firebase 的默认行为也在做同样的事情,它被计为 20QPS。 这是一些奇怪的谷歌速率限制会计规则。 所以我的解决方案只是添加重试。

缺点是,它会呼叫两次,所以如果呼叫是计费的,它可能会计费两次。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM