web-dev-qa-db-ja.com

Firebaseは現在のユーザーを追い出します

そのため、新しいユーザーアカウントを追加するたびに、既にサインインしている現在のユーザーが追い出されるという問題があります。firebaseapiを読んで、「If the new account作成された場合、ユーザーは自動的にサインインします」しかし、それを避けることについて他に何も言わなかった.

      //ADD EMPLOYEES
      addEmployees: function(formData){
        firebase.auth().createUserWithEmailAndPassword(formData.email, formData.password).then(function(data){
          console.log(data);
        });
      },

私は管理者であり、アカウントをサイトに追加しています。ログアウトせずに新しいアカウントにサインインしてアカウントを追加できる場合、それを希望します。これを回避する方法はありますか?

42
Victor Le

20161110を更新-以下の元の回答

また、別のアプローチについては、 this answer も確認してください。

元の答え

これは実際に可能です。

ただし、直接ではなく、2番目の認証参照を作成し、それを使用してユーザーを作成します。

var config = {apiKey: "apiKey",
    authDomain: "projectId.firebaseapp.com",
    databaseURL: "https://databaseName.firebaseio.com"};
var secondaryApp = firebase.initializeApp(config, "Secondary");

secondaryApp.auth().createUserWithEmailAndPassword(em, pwd).then(function(firebaseUser) {
    console.log("User " + firebaseUser.uid + " created successfully!");
    //I don't know if the next statement is necessary 
    secondaryApp.auth().signOut();
});

操作に使用するFirebase接続を指定しない場合、デフォルトで最初の接続が使用されます。

ソース 複数のアプリ参照の場合。

[〜#〜] edit [〜#〜]

新しいユーザーを実際に作成する場合、アカウントを作成するために必要なのは認証参照そのものであるため、2番目の認証参照で認証された管理者以外のユーザーや人物がいなくてもかまいません。

以下はテストされていませんが、考えてみてください

考えなければならないことは、Firebaseにデータを書き込むことです。一般的な方法は、ユーザーが自分のユーザー情報を編集/更新できるため、これを作成するために2番目の認証参照を使用するときに機能することです。ただし、そのユーザーのロールや許可などがある場合は、適切な許可を持つ認証参照を使用して作成してください。この場合、メイン認証は管理者で、2番目の認証は新しく作成されたユーザーです。

80
André Kool

20161108の更新-以下の元の回答

Firebaseは、firebase-admin SDKをリリースしました。これにより、このおよびその他の一般的な管理ユースケースのサーバー側コードが可能になります。 インストール手順 を読んでから ユーザー作成のドキュメント に飛び込みます。

元の回答

これは現在不可能です。 Email + Passwordユーザーを作成すると、その新しいユーザーが自動的にサインインします。

16

私は同様の問題を抱えていたので、Firebase Slackコミュニティで質問をしました。私はこれを実装しましたが、それは魅力のように機能します。

Try this

6
srijanshukla

Andréの非常に巧妙な回避策 Firebaseを使用してObjective-Cで作業するiOS SDK

NSString *plistPath = [[NSBundle mainBundle] pathForResource:@"GoogleService-Info" ofType:@"plist"];
FIROptions *secondaryAppOptions = [[FIROptions alloc] initWithContentsOfFile:plistPath];
[FIRApp configureWithName:@"Secondary" options:secondaryAppOptions];
FIRApp *secondaryApp = [FIRApp appNamed:@"Secondary"];
FIRAuth *secondaryAppAuth = [FIRAuth authWithApp:secondaryApp];

[secondaryAppAuth createUserWithEmail:user.email
                             password:user.password
                           completion:^(FIRUser * _Nullable user, NSError * _Nullable error) {
                                [secondaryAppAuth signOut:nil];
                          }];
3

Firestoreドキュメントが作成されたときにトリガーするFirebase Functionを作成しました(ルールは管理ユーザーのみに書き込み専用)。次に、admin.auth()。createUser()を使用して、新しいユーザーを適切に作成します。

export const createUser = functions.firestore
.document('newUsers/{userId}')
.onCreate(async (snap, context) => {
    const userId = context.params.userId;
    const newUser = await admin.auth().createUser({
        disabled: false,
        displayName: snap.get('displayName'),
        email: snap.get('email'),
        password: snap.get('password'),
        phoneNumber: snap.get('phoneNumber')
    });
    // You can also store the new user in another collection with extra fields
    await admin.firestore().collection('users').doc(newUser.uid).set({
        uid: newUser.uid,
        email: newUser.email,
        name: newUser.displayName,
        phoneNumber: newUser.phoneNumber,
        otherfield: snap.get('otherfield'),
        anotherfield: snap.get('anotherfield')
    });
    // Delete the temp document
    return admin.firestore().collection('newUsers').doc(userId).delete();
});

Algoはfunctions.https.onCall()を使用できます

exports.createUser= functions.https.onCall((data, context) => {
    const uid = context.auth.uid; // Authorize as you want
    // ... do the same logic as above
});

それを呼び出します。

const createUser = firebase.functions().httpsCallable('createUser');
createUser({userData: data}).then(result => {
    // success or error handling
});

Swift 4の更新

単一のアカウントから複数のユーザーを作成するためにいくつかの異なるオプションを試しましたが、これは間違いなく最良かつ最も簡単なソリューションです。

Nico による元の回答

最初にAppDelegate.Swiftファイルでfirebaseを構成します

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    // Override point for customization after application launch.
    FirebaseApp.configure()
    FirebaseApp.configure(name: "CreatingUsersApp", options: FirebaseApp.app()!.options)

    return true
}

アカウントを作成するアクションに次のコードを追加します。

            if let secondaryApp = FirebaseApp.app(name: "CreatingUsersApp") {
                let secondaryAppAuth = Auth.auth(app: secondaryApp)

                // Create user in secondary app.
                secondaryAppAuth.createUser(withEmail: email, password: password) { (user, error) in
                    if error != nil {
                        print(error!)
                    } else {
                        //Print created users email.
                        print(user!.email!)

                        //Print current logged in users email.
                        print(Auth.auth().currentUser?.email ?? "default")

                        try! secondaryAppAuth.signOut()

                    }
                }
            }
        }
2
BSlade

Swiftバージョン:

FIRApp.configure()

// Creating a second app to create user without logging in
FIRApp.configure(withName: "CreatingUsersApp", options: FIRApp.defaultApp()!.options)

if let secondaryApp = FIRApp(named: "CreatingUsersApp") {
    let secondaryAppAuth = FIRAuth(app: secondaryApp)
    secondaryAppAuth?.createUser(...)
}
0
Nico

Polymer and Firebase(polymerfire)を使用している場合は、この回答を参照してください: https://stackoverflow.com/a/46698801/18216

基本的に、セカンダリを作成します<firebase-app>現在のユーザーに影響を与えずに新しいユーザー登録を処理します。

0
Evan Caldwell

Androidソリューション(Kotlin):

1. apiキー、db urlなどを設定するにはFirebaseOptions BUILDER(!)が必要です。最後にbuild()を呼び出すことを忘れないでください

2. FirebaseApp.initializeApp()を呼び出してセカンダリ認証変数を作成します

3.新しく作成されたセカンダリ認証を渡すことでFirebaseAuthのインスタンスを取得し、必要なことを行います(例:createUser)

    // 1. you can find these in your project settings under general tab
    val firebaseOptionsBuilder = FirebaseOptions.Builder()
    firebaseOptionsBuilder.setApiKey("YOUR_API_KEY")
    firebaseOptionsBuilder.setDatabaseUrl("YOUR_DATABASE_URL")
    firebaseOptionsBuilder.setProjectId("YOUR_PROJECT_ID")
    firebaseOptionsBuilder.setApplicationId("YOUR_APPLICATION_ID") //not sure if this one is needed
    val firebaseOptions = firebaseOptionsBuilder.build()

    // indeterminate progress dialog *ANKO*
    val progressDialog = indeterminateProgressDialog(resources.getString(R.string.progressDialog_message_registering))
    progressDialog.show()

    // 2. second auth created by passing the context, firebase options and a string for secondary db name
    val newAuth = FirebaseApp.initializeApp(this@ListActivity, firebaseOptions, Constants.secondary_db_auth)
    // 3. calling the create method on our newly created auth, passed in getInstance
    FirebaseAuth.getInstance(newAuth).createUserWithEmailAndPassword(email!!, password!!)
    .addOnCompleteListener { it ->

        if (it.isSuccessful) {

            // 'it' is a Task<AuthResult>, so we can get our newly created user from result
            val newUser = it.result.user

            // store wanted values on your user model, e.g. email, name, phonenumber, etc.
            val user = User()
            user.email = email
            user.name = name
            user.created = Date().time
            user.active = true
            user.phone = phone

            // set user model on /db_root/users/uid_of_created_user/, or wherever you want depending on your structure
            FirebaseDatabase.getInstance().reference.child(Constants.db_users).child(newUser.uid).setValue(user)

            // send newly created user email verification link
            newUser.sendEmailVerification()

            progressDialog.dismiss()

            // sign him out
            FirebaseAuth.getInstance(newAuth).signOut()
            // DELETE SECONDARY AUTH! thanks, Jimmy :D
            newAuth.delete()

        } else {

            progressDialog.dismiss()

            try {

                throw it.exception!!

                // catch exception for already existing user (e-mail)
            } catch (e: FirebaseAuthUserCollisionException) {

                alert(resources.getString(R.string.exception_FirebaseAuthUserCollision), resources.getString(R.string.alertDialog_title_error)) {

                    okButton {

                        isCancelable = false

                    }

                }.show()

            }

        }

    }
0
fkvestak

Swift 5:シンプルなソリューション

最初に、現在のユーザーをoriginalUserという変数に保存します

let originalUser = Auth.auth().currentUser

次に、新しいユーザーを作成する完了ハンドラーで、updateCurrentUserメソッドを使用して元のユーザーを復元します

Auth.auth().updateCurrentUser(originalUser, completion: nil)
0
caesic

Firebase関数を使用してユーザーを追加できます。

const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();

const cors = require('cors')({
Origin: true,
});
exports.AddUser = functions.https.onRequest(( req, res ) => {
// Grab the text parameter.

cors( req, res, ()  => {
    let email  = req.body.email;
    let passwd = req.body.passwd;
    let role   = req.body.role;
    const token = req.get('Authorization').split('Bearer ')[1];

    admin.auth().verifyIdToken(token)
    .then(
            (decoded) => { 
             // return res.status(200).send(  decoded )
             return creatUser(decoded);
            })
    .catch((err) => {
            return res.status(401).send(err) 
     });

    function creatUser(user){
      admin.auth().createUser({
          email: email,
          emailVerified: false,
          password: passwd,
          disabled: false
        })
        .then((result) => {
          console.log('result',result);
           return res.status(200).send(result);
        }).catch((error) => {
           console.log(error.message);
           return res.status(400).send(error.message);
       })
     }

   }); 
 });

Androidソリューション(Java):

大したことはありません。それをJavaに変更し、Androidインターンシップのタスク参照としてのソリューションに感謝します。 https://stackoverflow.com/a/52162643/11726855

FirebaseAuth fba = FirebaseAuth.getInstance();
DatabaseReference dbr = FirebaseDatabase.getInstance().getReference("users");
ProgressDialog pd = new ProgressDialog(this);

public void [ON_CLICK](View view) {
    pd.setMessage("Adding User....");
    pd.show();

    //These can be found in your project settings under General tab
    //Server key under Cloud Messaging tab is not the API key, I've been confused by other posts
    FirebaseOptions.Builder fbo = new FirebaseOptions.Builder();
    fbo.setApiKey("YOUR_WEB_API_KEY");
    fbo.setDatabaseUrl("https://[YOUR_PROJECT_ID].firebaseio.com/");
    fbo.setProjectId("YOUR_PROJECT_ID");
    fbo.setApplicationId("YOUR_APP_ID"); //Tested, App Id is required.
    FirebaseOptions firebaseOptions = fbo.build();
    final FirebaseApp secondaryAuth = FirebaseApp.initializeApp([Java_CLASS_NAME].this, firebaseOptions, "secondary_db_auth");

    FirebaseAuth.getInstance(secondaryAuth).createUserWithEmailAndPassword(addUserEmail, addUserPassword)
        .addOnCompleteListener(this,
                new OnCompleteListener<AuthResult>() {
                    @Override
                    public void onComplete(@NonNull Task<AuthResult> task) {
                        pd.dismiss();
                        if (task.isSuccessful()) {
                            //Can inline as "dbr.child(addUserName).setValue(users);", but I don't like the green box
                            String key = addUserName;

                            //Reusable constructor
                            UserFD users = new UserFD(addUserName, addUserPassword, addUserAuthorisation);
                            dbr.child(key).setValue(users);
                            throwSecondaryAuth(secondaryAuth);
                            Toast.makeText(getApplicationContext(),
                                    "Add User Successful", Toast.LENGTH_SHORT).show();
                        } else {
                            //Sorry that still weak in playing with exception, so I use toast                                
                            throwSecondaryAuth(secondaryAuth);
                            Toast.makeText(getApplicationContext(),
                                    "Add User Failed", Toast.LENGTH_SHORT).show();
                        }
                    }
                });
}

ここにプロジェクトID、APIキー、アプリIDがあります

これはデータベースURLです

物事を再利用可能にしましょう......

public void throwSecondaryAuth(FirebaseApp secondAuth) {
    FirebaseAuth.getInstance(secondAuth).signOut();
    secondAuth.delete();
}
0
Yap Kiew Seng

Swift 3 Cabreraの答え の3つの適応:

let bundle = Bundle.main
        let path = bundle.path(forResource: "GoogleService-Info", ofType: "plist")!
        let options = FIROptions.init(contentsOfFile: path)
        FIRApp.configure(withName: "Secondary", options: options!)
        let secondary_app = FIRApp.init(named: "Secondary")
        let second_auth = FIRAuth(app : secondary_app!)
        second_auth?.createUser(withEmail: self.username.text!, password: self.password.text!)
        {
            (user,error) in
            print(user!.email!)
            print(FIRAuth.auth()?.currentUser?.email ?? "default")
        }
0
sanket pahuja