【问题标题】:How do I return a list of users if I use the Firebase simple username & password authentication如果我使用 Firebase 简单的用户名和密码身份验证,如何返回用户列表
【发布时间】:2026-01-07 22:05:02
【问题描述】:

不确定我是否做错了什么,但使用这个 api https://www.firebase.com/docs/security/simple-login-email-password.html 我可以成功创建一个用户 - 根据返回消息,但我在 Forge 控制台的任何地方都看不到该用户。您如何知道注册了哪些用户?

我应该获取返回的用户 ID 并在 Firebase 中创建自己的用户对象,还是这种重复是不必要的。我确实需要添加一些额外的用户属性,所以也许我还是需要这样做。

【问题讨论】:

    标签: firebase firebase-authentication


    【解决方案1】:

    在 Firebase 身份验证(以前称为 Firebase SimpleLogin)中使用电子邮件/密码身份验证时,用户的电子邮件和密码组合与实际存储在 Firebase 中的数据分开安全存储。

    Firebase 中的数据与用户的电子邮件/密码哈希组合之间的屏障是设计使然:我们希望让您更轻松地 (1) 开发应用程序,(2) 防止任何意外的用户凭据泄露, (3) 在如何将用户数据存储在 Firebase 中时,您仍然可以拥有完全的灵活性。

    这意味着我们只存储电子邮件地址/密码哈希组合而不存储其他任何内容,因此您可以决定如何在 Firebase 中存储实际用户数据。正如您所建议的,您应该获取用户 ID 并将该数据存储在您的 Firebase 中的某个位置,例如 /users/$id,并使用 Firebase Security Rules Language 来确定对该数据的读/写访问权限。您的用户唯一的idemail 已经在您将在编写规则时使用的auth 变量中。

    【讨论】:

    • 感谢您的信息 - 我认为那里存在依赖关系,但如果我为每个用户存储的数据不同步,比如意外删除,我怎么知道当前谁可以访问我的应用程序?数据是分开的很好,但肯定会被我从管理 POV 中看不到的事实所否定?
    • 列出所有创建的用户和删除用户看起来是必须的!
    • 可通过控制台访问的用户列表现在又回到了新的 Google 的 Firebase 中
    • 这是一个必须具备的...
    • 感谢弗兰克的回答。但是,如果您正在谈论的单独的用户数据库只存储电子邮件/密码组合(而不是任何其他用户信息),为什么在 Manager Users 部分(firebase.google.com/docs/auth/web/manage-users)下他们提到user.updateProfile 具有保存能力的方法displayNamephotoURL?那么这些信息会存储在哪里呢?它没有保存在我的 Firestore 中 - 我检查过 - 所以我假设它在那个单独的数据库中。如果当前用户是唯一可以看到的人,那么这种方法的意义何在?
    【解决方案2】:

    你可以使用admin.auth().listUsers来做到这一点

    这是相关文档:https://firebase.google.com/docs/reference/admin/node/admin.auth.Auth.html#listusers

    还有一个用法示例:https://firebase.google.com/docs/auth/admin/manage-users#list_all_users

    function listAllUsers(nextPageToken) {
      // List batch of users, 1000 at a time.
      admin.auth().listUsers(1000, nextPageToken)
        .then(function(listUsersResult) {
          listUsersResult.users.forEach(function(userRecord) {
            console.log('user', userRecord.toJSON());
          });
          if (listUsersResult.pageToken) {
            // List next batch of users.
            listAllUsers(listUsersResult.pageToken);
          }
        })
        .catch(function(error) {
          console.log('Error listing users:', error);
        });
    }
    // Start listing users from the beginning, 1000 at a time.
    listAllUsers();
    

    【讨论】:

    • 不应该在客户端使用管理库?
    • 是的,管理员仅用于服务器端(出于安全原因)。但是如果你需要客户端的信息,你可以做一个中间 API。
    • 好主意。 Firestore 仍然不允许在用户内部存储用户信息(我觉得这很愚蠢:D)所以您需要一次在 Firestore 中创建一个用户列表 ^^
    • 请注意,如果您不想创建“API”,您仍然可以依赖 firebase“函数”
    • 但是如果你使用firebase“函数”,你仍然需要验证请求(使用类似jwt的东西)对吧?或者有什么办法解决它(它应该是安全的)?顺便说一句,我使用的是实时数据库,而不是 firestore。
    【解决方案3】:

    在这里,我创建了一个 Android 程序来执行 Rob 为 firebase 初学者(如我)所说的内容 out there.this程序首先存储signedUp或signedIn用户的用户名,然后将它们显示在listView中

    SignInActivity.java

    public class SignInActivity extends BaseActivity implements View.OnClickListener,View.OnKeyListener{
    
        private DatabaseReference mDatabase;
        public static FirebaseAuth mAuth;
        private static final String TAG = "MainActivity";
    
        EditText usernameField;
        EditText passwordField;
        TextView changeSignUpModeTextView;
        Button signUpButton;
        ImageView logo;
        RelativeLayout relativeLayout;
    
        Boolean signUpModeActive;
        static ArrayList<String> userList = new ArrayList<>();
    
        @Override
        public void onStart() {
            super.onStart();
    
            // Check auth on Activity start
            if (mAuth.getCurrentUser() != null) {
                onAuthSuccess(mAuth.getCurrentUser());
            }
        }
        @Override
        public boolean onKey(View view, int i, KeyEvent keyEvent) {
    
            if(i == keyEvent.KEYCODE_ENTER && keyEvent.getAction() == keyEvent.ACTION_DOWN){
                signUpOrLogIn(view);
            }
             return false;
        }
    
        @Override
        public void onClick(View view) {
    
            if(view.getId() == R.id.changeSignUpMode){
    
                if (signUpModeActive == true){
    
                    signUpModeActive = false;
                    changeSignUpModeTextView.setText("Sign Up");
                    signUpButton.setText("Log In");
    
                }else{
    
                    signUpModeActive = true;
                    changeSignUpModeTextView.setText("Log In");
                    signUpButton.setText("Sign Up");
                }
    
            }else if(view.getId() == R.id.logo || view.getId() == R.id.relativeLayout){
    
                InputMethodManager inm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
                inm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(),0);
    
            }
    
        }
    
    
        public void signUpOrLogIn(View view) {
    
            showProgressDialog();
            String email = usernameField.getText().toString().trim();
            String password = passwordField.getText().toString().trim();
    
            if (signUpModeActive == true) {
                mAuth.createUserWithEmailAndPassword(email,password)
                        .addOnCompleteListener(MainActivity.this, new OnCompleteListener<AuthResult>() {
                            @Override
                            public void onComplete(@NonNull Task<AuthResult> task) {
                                hideProgressDialog();
                                Toast.makeText(MainActivity.this, "createUserWithEmail:onComplete:" + task.isSuccessful(), Toast.LENGTH_SHORT).show();
                                // If sign in fails, display a message to the user. If sign in succeeds
                                // the auth state listener will be notified and logic to handle the
                                // signed in user can be handled in the listener.
                                if (!task.isSuccessful()) {
                                    Toast.makeText(MainActivity.this, "Authentication failed." + task.getException().toString().substring(task.getException().toString().indexOf(" ")),
                                            Toast.LENGTH_SHORT).show();
                                    Log.i("Error", task.getException().toString());
                                } else {
                                    onAuthSuccess(task.getResult().getUser());
                                    showUserList();
                                }
                            }
                        });
            } else {
                mAuth.signInWithEmailAndPassword(email,password)
                        .addOnCompleteListener(MainActivity.this, new OnCompleteListener<AuthResult>() {
                            @Override
                            public void onComplete(@NonNull Task<AuthResult> task) {
                                hideProgressDialog();
                                // If sign in fails, display a message to the user. If sign in succeeds
                                // the auth state listener will be notified and logic to handle the
                                // signed in user can be handled in the listener.
                                if (!task.isSuccessful()) {
                                    // there was an error
    
                                    Toast.makeText(MainActivity.this, task.getException().toString(),
                                            Toast.LENGTH_LONG).show();
                                } else
    
                                {
                                    onAuthSuccess(task.getResult().getUser());
                                    showUserList();
                                }
                            }
                        });
            }
        }
    
        public void showUserList(){
            startActivity(new Intent(getApplicationContext(), UserList.class));
            finish();
        }
        private void onAuthSuccess(FirebaseUser user) {
            String username = usernameFromEmail(user.getEmail());
    
            // Write new user
            writeNewUser(user.getUid(), username, user.getEmail());
    
            // Go to MainActivity
    
        }
        private String usernameFromEmail(String email) {
            if (email.contains("@")) {
                return email.split("@")[0];
            } else {
                return email;
            }
        }
    
        private void writeNewUser(String userId, String name, String email) {
            User user = new User(name, email);
    
            mDatabase.child("users").child(userId).setValue(user);
            ArrayList<String> userNames = new ArrayList<>();
            userNames.add(name);
            mDatabase.child("usernamelist").setValue(userNames);
        }
    
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            mAuth = FirebaseAuth.getInstance();
            mDatabase = FirebaseDatabase.getInstance().getReference();
    
    
            if(mAuth.getCurrentUser()!=null){
                showUserList();
            }
    
            usernameField = (EditText) findViewById(R.id.username);
            passwordField = (EditText) findViewById(R.id.password);
            changeSignUpModeTextView = (TextView) findViewById(R.id.changeSignUpMode);
            signUpButton = (Button) findViewById(R.id.signupbutton);
            logo = (ImageView)findViewById(R.id.logo);
            relativeLayout= (RelativeLayout)findViewById(R.id.relativeLayout);
    
            signUpModeActive = true;
    
            changeSignUpModeTextView.setOnClickListener(this);
    
            usernameField.setOnKeyListener(this);
            passwordField.setOnKeyListener(this);
    
            logo.setOnClickListener(this);
            relativeLayout.setOnClickListener(this);
    
    
    
        }
    }
    

    UserList.java

    public class UserList extends AppCompatActivity {
    
        private static final String TAG = "UserList" ;
        private DatabaseReference userlistReference;
        private ValueEventListener mUserListListener;
        ArrayList<String> usernamelist = new ArrayList<>();
        ArrayAdapter arrayAdapter;;
    
        ListView userListView;
    
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_user_list);
            userlistReference = FirebaseDatabase.getInstance().getReference().child("usernamelist");
            onStart();
            userListView = (ListView) findViewById(R.id.userlistview);
    
    
        }
    
        @Override
        protected void onStart() {
            super.onStart();
            final ValueEventListener userListener = new ValueEventListener() {
                @Override
                public void onDataChange(DataSnapshot dataSnapshot) {
                    usernamelist = new ArrayList<>((ArrayList) dataSnapshot.getValue());
                    usernamelist.remove(usernameOfCurrentUser());
                    Log.i(TAG, "onDataChange: "+usernamelist.toString());
                    arrayAdapter = new ArrayAdapter(UserList.this,android.R.layout.simple_list_item_1,usernamelist);
                    userListView.setAdapter(arrayAdapter);
                }
    
                @Override
                public void onCancelled(DatabaseError databaseError) {
                    Log.w(TAG, "onCancelled: ",databaseError.toException());
                    Toast.makeText(UserList.this, "Failed to load User list.",
                            Toast.LENGTH_SHORT).show();
                }
            };
            userlistReference.addValueEventListener(userListener);
    
            mUserListListener = userListener;
        }
        public String usernameOfCurrentUser()
        {
            String email = MainActivity.mAuth.getCurrentUser().getEmail();
            if (email.contains("@")) {
                return email.split("@")[0];
            } else {
                return email;
            }
        }
        @Override
        public void onStop() {
            super.onStop();
    
            // Remove post value event listener
            if (mUserListListener != null) {
                userlistReference.removeEventListener(mUserListListener);
            }
    
        }
    
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            getMenuInflater().inflate(R.menu.menu_main, menu);
            return true;
        }
    
        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
            switch(item.getItemId()) {
                case R.id.action_logout:
                    FirebaseAuth.getInstance().signOut();
                    startActivity(new Intent(this, MainActivity.class));
                    finish();
                    return true;
                default:
                    return super.onOptionsItemSelected(item);
            }
        }
    }
    

    【讨论】:

      【解决方案4】:

      我会尽可能简单地回答 只需使用以下代码将注册用户添加到您的数据库中

      您也可以使用共享首选项将数据保存在本地,但其他用户无法使用。

      在数据库中保存用户列表后,只需使用适配器从那里检索它

      FirebaseDatabase.getInstance().getReference().child("my_user")
                              .child(task.getResult().getUser().getUid())
                              .child("username").setValue(autoCompleteTextView1.getText().toString());
      

      【讨论】:

        【解决方案5】:

        可以使用云功能来获取用户列表(查看文档firebase)。请注意,在以下示例中,custom claims 功能用于检查用户是否具有足够的权限。

        // USERS: return full users list for admin
        // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
        import * as admin from 'firebase-admin'
        import * as functions from 'firebase-functions'
        
        export const listUsers = functions.https.onCall((data, context) => {
          // check if user is admin (true "admin" custom claim), return error if not
          const isAdmin = context.auth.token.admin === true
          if (!isAdmin) {
            return { error: `Unauthorized.` }
          }
        
          return admin
            .auth()
            .listUsers()
            .then((listUsersResult) => {
              // go through users array, and deconstruct user objects down to required fields
              const result = listUsersResult.users.map((user) => {
                const { uid, email, photoURL, displayName, disabled } = user
                return { uid, email, photoURL, displayName, disabled }
              })
        
              return { result }
            })
            .catch((error) => {
              return { error: 'Error listing users' }
            })
        })
        

        【讨论】:

          【解决方案6】:

          您可以使用Google Identity Toolkit API 来获取您的Firebase 项目中所有注册用户的列表,此API 由Firebase CLI 使用,可以通过运行firebase auth:export results-file 来访问

          确保身份工具包 API 已启用

          firebase-users-list.js

          const serviceAccount = require('path/to/firebase-sdk-json-service-account');
          
          const googleapis = require('googleapis');
          const identitytoolkit = googleapis.identitytoolkit('v3');
          
          const authClient = new googleapis.auth.JWT(
              serviceAccount.client_email,
              null,
              serviceAccount.private_key,
              ['https://www.googleapis.com/auth/firebase'],
              null
          );
          
          authClient.authorize((err) => {
              if (err) {
                  return console.error(err);
              }
          
              let nextPageToken = undefined;
              let users = [];
              const getAccounts = () => identitytoolkit.relyingparty.downloadAccount({
                  auth: authClient,
                  resource: {
                      targetProjectId: serviceAccount.project_id,
                      maxResults: 200,
                      nextPageToken: nextPageToken
                  }
              }, (e, results) => {
                  if (e) {
                      return console.error(err);
                  }
          
                  users = users.concat(results.users);
                  if (results.nextPageToken) {
                      nextPageToken = results.nextPageToken;
                      return getAccounts();
                  } else {
                      console.log(users);
                  }
              });
              getAccounts();
          });
          

          【讨论】:

            【解决方案7】:

            python中的用户列表:

            from firebase_admin import credentials, db, auth
            cred = credentials.Certificate('\path\to\serviceAccountKey.json')
            default_app = firebase_admin.initialize_app(cred, {
                "databaseURL": "https://data_base_url.firebaseio.com"
            })
            users = auth.list_users()
            

            【讨论】:

              最近更新 更多