如何在Firebase 3.x中禁用注册

如何在Firebase 3.x中禁用注册,firebase,firebase-realtime-database,firebase-authentication,Firebase,Firebase Realtime Database,Firebase Authentication,我已经创建了一些使用firebase.auth()的用户。使用Email和Password登录,现在想停止注册,但要让登录继续工作。我尝试了一些针对用户的规则,甚至完全停止向firebase写信。然而,注册仍然是可能的。在控制台中禁用电子邮件/密码也会禁用登录 { "rules": { ".read": true, ".write": false, } } 您知道如何将安全规则应用于Firebase 3中的用户吗?Firebase明确地将身份验证

我已经创建了一些使用firebase.auth()的用户。使用Email和Password登录,现在想停止注册,但要让登录继续工作。我尝试了一些针对用户的规则,甚至完全停止向firebase写信。然而,注册仍然是可能的。在控制台中禁用电子邮件/密码也会禁用登录

{
  "rules": {
        ".read": true,
        ".write": false,
      }
}

您知道如何将安全规则应用于Firebase 3中的用户吗?

Firebase明确地将身份验证(登录应用程序)与授权(从应用程序访问数据库或存储资源)分开

如果不禁用所有用户的登录,则无法禁用注册,这不是您想要的

在典型的场景中,开发人员将开始基于经过身份验证的用户保护数据库/文件访问。有关和,请参见文档中的相关章节

如果您的用例是只希望特定用户具有访问权限,那么您可能需要实现一个白名单:一个允许访问数据的用户列表

您可以在安全规则中执行此操作:

{
  "rules": {
        ".read": "auth.uid == '123abc' || auth.uid == 'def456'",
        ".write": false,
      }
}
"allowedUids": {
    "123abc": true,
    "def456": true
}
或者(更好)将允许的UID列表放在数据库中,并从安全规则中引用:

{
  "rules": {
        ".read": "auth.uid == '123abc' || auth.uid == 'def456'",
        ".write": false,
      }
}
"allowedUids": {
    "123abc": true,
    "def456": true
}
然后:

{
  "rules": {
        ".read": "root.child('allowedUids').child(auth.uid).exists()",
        ".write": false,
      }
}

这个问题已经问了好几天了,但这可能会帮助那些仍然想知道答案的人,我们仍然不能简单地禁用新帐户创建,但我们可以使用Firebase功能:

以下是使用云功能自动禁用新用户的解决方案

const functions=require('firebase-functions');
const admin=require('firebase-admin');
exports.blockSignup=functions.auth.user().onCreate(事件=>{
返回admin.auth()
.updateUser(event.uid,{disabled:true})
.then(userRecord=>console.log(`Auto-blocked user:${userRecord.toJSON()}`)
.catch(error=>console.log(`error auto blocking:${error}`));
});
请记住,当您使用Firebase web控制台或第三方创建用户时,会触发此函数。
因此,您必须创建、等待函数,然后启用用户。

如果您想从Android应用程序的
FirebaseUI
中删除注册选项,则必须添加以下提供商:

new AuthUI.IdpConfig.EmailBuilder().setAllowNewAccounts(false).build());
该函数将如下所示:

private void FireBaseLoginUI() {
        List<AuthUI.IdpConfig> providers = Collections.singletonList(
                new AuthUI.IdpConfig.EmailBuilder().setAllowNewAccounts(false).build());

        startActivityForResult(
                AuthUI.getInstance()
                        .createSignInIntentBuilder()
                        .setAvailableProviders(providers)
                        .setLogo(R.drawable.app_logo)
                        .setTheme(R.style.AuthUITheme)
                        .build(),
                RC_SIGN_IN);
}
private void FireBaseLoginUI(){
列表提供程序=Collections.singletonList(
新建AuthUI.IdpConfig.EmailBuilder().setAllowneWaAccounts(false.build());
startActivityForResult(
AuthUI.getInstance()
.CreateSignInEntBuilder()
.setAvailableProviders(提供程序)
.setLogo(R.drawable.app_logo)
.setTheme(R.style.authuithem)
.build(),
RC_登录);
}

如上所述,区分身份验证和授权很重要。因此,这也可以在Firebase之外进行。例如,如果您正在构建一个web应用程序,并且希望允许特定的用户列表访问给定页面,那么您可以在web应用程序中处理它

此示例用于执行onCall firebase函数。仅当用户UID为
12345

exports.ILoveConsole = functions.https.onCall((message, context) => {

//message is just a text
//context hold the user auth information

    'use strict';
        if (context && context.auth && context.auth.uid) {
            if(context.auth.uid === "12345"){
                console.log("I love security");
            }
            else{
                console.log("You are authenticated but not authorized");
            }
        }
        else {
            console.log("You are neither authenticated nor authorized");
        }
});

注意:如果要创建用户列表,可以使用for循环函数在浏览器中检查授权用户的数组,也可以调用firebase函数。它们都应该在加载页面之前运行

我使用以下方法:

// The Cloud Functions for Firebase SDK to create Cloud Functions and setup triggers.
const functions = require('firebase-functions');
const admin = require("firebase-admin");

admin.initializeApp();

exports.blockSignup = functions.auth.user().onCreate(event => {
    if (process.env['allowCreation'] === "false")
        return admin.auth().deleteUser(event.uid);
    else return Promise.resolve("letUserCreate");
});
创建我想要的用户后,转到并将环境变量更改为false、redeploy和done

或者,您可以将该用户添加到firestore,并且仅当该用户存在于firestore上时才允许注册。像这样:

// The Cloud Functions for Firebase SDK to create Cloud Functions and setup triggers.
const functions = require('firebase-functions');
const admin = require("firebase-admin");

admin.initializeApp();

exports.blockSignup = functions.auth.user().onCreate(user => {
    return new Promise((resolve, reject) => {
        admin.firestore().collection('users').doc(user.email).get().then(doc => {
            if (doc.exists) {
                resolve("letUserCreate");
            }
            else {
                reject(admin.auth().deleteUser(user.uid))
            }
        }).catch(reason => {
            console.error(reason)
            reject(admin.auth().deleteUser(user.uid))
        })
    });
});

谢谢你的快速回复。它解决了我的问题。如果我的答案有用,请单击它左侧的向上投票按钮。如果它回答了您的问题,请单击复选标记接受它。这样别人就知道你得到了(足够的)帮助。很好的解决方法。还是希望他们加入这个功能。如果我们有200个测试员,并且必须像这样手动添加它们,那将是一个大混乱。我对我们的大多数大型演示项目都采用这种方法,实际上它是相当可扩展的。如果在数据库控制台中添加UID的工作太多,请创建一个简单的web管理页面来添加它们。当然,只允许管理员(您在类似的白名单上跟踪)写入此位置。谢谢!看起来允许您禁用新注册是一个合理的功能,但这对我很有帮助:)它很有效。但是,它允许使用例如google provider和signInWithPopup()方法进行首次登录。看起来帐户禁用功能随后出现。尽管如此,这仍然是可以克服的,因为在signInWithPopup()调用之后,我们有一个UserCredential类型的承诺,它有一个额外的UserInfo.isNewUser字段,我们可以立即注销用户。这应该是一个简单的操作。控制台上的一个简单按钮,用于启用或禁用新用户创建!需要添加
const functions=require('firebase-functions')也是。我如何处理此错误:firebase_config和gcloud_项目环境变量丢失这是正确答案,但如果您按照所述实现它,则会出现以下错误:java.lang.IllegalArgumentException:每个提供程序只能设置一次。密码设置了两次,所以要删除它,您只需在一个电子邮件提供程序上使用,如下所示:List providers=Arrays.asList(new AuthUI.IdpConfig.EmailBuilder().setAllowneWaAccounts(false.build());