programing

Firebase가 현재 사용자를 제거합니다.

magicmemo 2023. 6. 20. 21:32
반응형

Firebase가 현재 사용자를 제거합니다.

따라서 새 사용자 계정을 추가할 때마다 이미 로그인한 현재 사용자가 삭제되는 문제가 있습니다.파이어베이스 api를 읽어보니 "새 계정이 생성되면 사용자가 자동으로 로그인됩니다."라고 되어 있었습니다. 하지만 그들은 그것을 피하는 것에 대해 다른 말을 한 적이 없습니다.

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

저는 관리자이고 제 사이트에 계정을 추가하고 있습니다.새 계정에 서명하고 서명하지 않고 계정을 추가할 수 있으면 좋겠습니다.어떻게든 피할 수 있을까요?

20161110 업데이트 - 아래 원본 답변

또한 다른 접근 방식을 사용하려면 이 답변을 확인하십시오.

원답

이것은 실제로 가능합니다.

그러나 직접적인 방법은 아니지만 두 번째 인증 참조를 생성하고 이를 사용하여 사용자를 생성하는 것입니다.

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 연결을 지정하지 않으면 기본적으로 첫 번째 연결이 사용됩니다.

여러 앱 기본 설정의 원본입니다.

편집

새 사용자를 실제로 생성하는 경우 두 번째 인증 참조에서 인증된 관리자 이외의 사용자가 없어도 상관 없습니다. 계정을 생성하는 데 필요한 것은 인증 참조 자체이기 때문입니다.

다음은 테스트되지 않았지만 고려해야 할 사항입니다.

여러분이 생각해야 할 것은 소방서에 데이터를 쓰는 것입니다.일반적으로 사용자는 자신의 사용자 정보를 편집/업데이트할 수 있으므로 두 번째 인증 참조를 사용하여 이 정보를 작성하면 됩니다.그러나 해당 사용자에 대한 역할이나 권한과 같은 권한이 있는 경우 올바른 권한을 가진 인증 참조를 사용하여 해당 권한을 작성해야 합니다.이 경우 기본 인증자는 admin이고 두 번째 인증자는 새로 생성된 사용자입니다.

20161108 업데이트 - 아래 원본 답변

Firebase는 방금 Firebase-admin SDK를 출시했는데, 이 SDK는 이 소프트웨어와 다른 일반적인 관리 사용 사례에 대한 서버 측 코드를 허용합니다.설치 지침을 읽은 다음 사용자 작성에 대한 설명서로 이동합니다.

원답

현재는 이 작업을 수행할 수 없습니다.Email+Password 사용자를 만들면 새 사용자가 자동으로 로그인됩니다.

방금 Firestore 문서가 작성될 때 트리거하는 Firebase 함수를 만들었습니다(관리자에 대한 쓰기 전용 규칙 포함).그런 다음 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로 사용할 수 있습니다.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 5: 간단한 솔루션

먼저 현재 사용자를 originalUser라는 변수에 저장합니다.

let originalUser = Auth.auth().currentUser

그런 다음 새 사용자 생성 완료 핸들러에서 updateCurrentUser 메서드를 사용하여 원래 사용자를 복원합니다.

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

다음은 웹 SDK를 사용하는 간단한 솔루션입니다.

  1. 클라우드 기능 생성(https://firebase.google.com/docs/functions)
import admin from 'firebase-admin';
import * as functions from 'firebase-functions';

const createUser = functions.https.onCall((data) => {
  return admin.auth().createUser(data)
    .catch((error) => {
      throw new functions.https.HttpsError('internal', error.message)
    });
});

export default createUser;
  1. 앱에서 이 기능 호출
import firebase from 'firebase/app';

const createUser = firebase.functions().httpsCallable('createUser');

createUser({ email, password })
  .then(console.log)
  .catch(console.error);
  1. 선택적으로 반환된 UID를 사용하여 사용자 문서 정보를 설정할 수 있습니다.
createUser({ email, password })
  .then(({ data: user }) => {
    return database
      .collection('users')
      .doc(user.uid)
      .set({
        firstname,
        lastname,
        created: new Date(),
      });
  })
  .then(console.log)
  .catch(console.error);

저는 Firebase iOS SDK를 사용하여 Objective-C에서 작업하는 André의 매우 영리한 해결책을 얻었습니다.

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];
                          }];

Swift 4용 업데이트

단일 계정에서 여러 사용자를 생성하기 위해 몇 가지 다른 옵션을 시도해 보았지만, 이것이 가장 좋고 쉬운 해결책입니다.

니코의 원답

먼저 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()
                        
                    }
                }
            }
        }

사용자 추가를 위해 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);
       })
     }

   }); 
 });

  CreateUser(){
//console.log('Create User')
this.submitted = true;
if (this.myGroup.invalid) {
  return;
}


let Email    = this.myGroup.value.Email;
let Passwd   = this.myGroup.value.Passwd;
let Role     = 'myrole';
let TechNum  = this.myGroup.value.TechNum;
let user     = JSON.parse(localStorage.getItem('user'));
let role     = user.role;
let AdminUid = user.uid;
let authToken = user.stsTokenManager.accessToken;
let httpHeaders = new HttpHeaders().set('Authorization', 'Bearer ' + authToken);
let options = { headers: httpHeaders };
let params  = { email:Email,passwd:Passwd,role:Role };

this.httpClient.post('https://us-central1-myproject.cloudfunctions.net/AddUser', params, options)
.subscribe( val => { 
           //console.log('Response from cloud function', val ); 
           let createdUser:any = val;
           //console.log(createdUser.uid);
           const userRef: AngularFirestoreDocument<any> = this.afs.doc(`users/${createdUser.uid}`);
                 const userUpdate = {
                             uid: createdUser.uid,
                             email: createdUser.email,
                             displayName: null,
                             photoURL: null,
                             emailVerified: createdUser.emailVerified,
                             role: Role,
                             TechNum:TechNum,
                             AccountAccess:this.AccountAccess,
                             UserStatus:'open',
                             OwnerUid:AdminUid,
                             OwnerUidRole:role,
                             RootAccountAccess:this.RootAccountAccess
                      }
                       userRef.set(userUpdate, {
                             merge: false
                       });
                          this.toastr.success('Success, user add','Success');
                          this.myGroup.reset();
                          this.submitted = false;
                       },
                       err => { 
                         console.log('HTTP Error', err.error)
                         this.toastr.error(err.error,'Error')
                       },
                       () => console.log('HTTP request completed.')
    );

}

웹에서 이는 등록 컨텍스트에서 createUserWithEmailAndPassword를 호출할 때 예기치 않은 동작(예: 새 사용자 계정을 생성하여 새 사용자를 앱에 초대) 때문입니다.

createUserWithEmailAndPassword 메서드는 새 새로 고침 토큰을 트리거하고 사용자 쿠키도 업데이트합니다.(이 부작용은 문서화되어 있지 않습니다)

다음은 웹 SDK에 대한 해결 방법입니다. 새 사용자를 만든 후:

firebase.auth().updateCurrentUser (loggedInUser.current)

기록을 시작하는 경우원래 사용자와 사전에 함께 사용합니다.

안녕하세요. 비슷한 문제가 있었습니다. 관리자를 통해 사용자를 생성하려고 합니다. 사인 없이 사용자를 등록할 수 없기 때문입니다. 로그인, 아래에 단계를 추가하여 관련 작업을 만들었습니다.

  1. 가입 대신 이메일을 키로 하여 파이어베이스 실시간 DB에 노드를 생성합니다(파이어베이스는 이메일을 키로 허용하지 않으므로 이메일에서 키를 생성하는 함수를 생성했습니다, 그 반대의 경우도 마찬가지입니다).
  2. 사용자를 저장하는 동안 초기 암호 필드 저장(원하는 경우 암호를 한 번만 사용할 수도 있음)
  3. 이제 Once 사용자가 로그인을 시도하면 해당 전자 메일(전자 메일에서 생성 키)이 있는 노드가 DB에 있는지 확인하고, 있으면 제공된 암호와 일치하는지 확인합니다.
  4. 암호가 일치하면 노드를 삭제하고 제공된 자격 증명으로 authSignUpWithEmail 및 Password를 수행합니다.
  5. 사용자가 성공적으로 등록되었습니다.
//Sign In
firebaseDB.child("users").once("value", (snapshot) => {
     const users = snapshot.val();
     const userKey = emailToKey(data.email);
     if (Object.keys(users).find((key) => key === userKey)) {
       setError("user already exist");
       setTimeout(() => {
         setError(false);
       }, 2000);
       setLoading(false);
     } else {
       firebaseDB
         .child(`users`)
         .child(userKey)
         .set({ email: data.email, initPassword: data.password })
         .then(() => setLoading(false))
         .catch(() => {
           setLoading(false);
           setError("Error in creating user please try again");
           setTimeout(() => {
             setError(false);
           }, 2000);
         });
     }
   });

//Sign Up 
signUp = (data, setLoading, setError) => {
 auth
   .createUserWithEmailAndPassword(data.email, data.password)
   .then((res) => {
     const userDetails = {
       email: res.user.email,
       id: res.user.uid,
     };
     const key = emailToKey(data.email);
     app
       .database()
       .ref(`users/${key}`)
       .remove()
       .then(() => {
         firebaseDB.child("users").child(res.user.uid).set(userDetails);
         setLoading(false);
       })
       .catch(() => {
         setLoading(false);
         setError("error while registering try again");
         setTimeout(() => setError(false), 4000);
       });
   })
   .catch((err) => {
     setLoading(false);
     setError(err.message);
     setTimeout(() => setError(false), 4000);
   });
};

//Function to create a valid firebase key from email and vice versa
const emailToKey = (email) => {
 //firebase do not allow ".", "#", "$", "[", or "]"
 let key = email;
 key = key.replace(".", ",0,");
 key = key.replace("#", ",1,");
 key = key.replace("$", ",2,");
 key = key.replace("[", ",3,");
 key = key.replace("]", ",4,");

 return key;
};

const keyToEmail = (key) => {
 let email = key;
 email = email.replace(",0,", ".");
 email = email.replace(",1,", "#");
 email = email.replace(",2,", "$");
 email = email.replace(",3,", "[");
 email = email.replace(",4,", "]");

 return email;
};

프런트 엔드에서 이 작업을 수행하려면 두 번째 인증 참조를 생성하여 다른 사용자를 생성하고 로그아웃한 후 해당 참조를 삭제합니다.이렇게 하면 새 사용자를 만들 때 로그아웃되지 않고 기본 Firebase 앱이 이미 존재한다는 오류가 발생하지 않습니다.

   const createOtherUser =()=>{
            var config = {
                //your firebase config
            };
            let secondaryApp = firebase.initializeApp(config, "secondary");

            secondaryApp.auth().createUserWithEmailAndPassword(email, password).then((userCredential) => {
                console.log(userCredential.user.uid);
            }).then(secondaryApp.auth().signOut()
            )
            .then(secondaryApp.delete()
            )


        }
        

업데이트 19.05.1987 - @fire/fire 사용(사용 가능한 업데이트 = v.7.3.0)

앱에서 직접 Firebase를 사용하지 않고 인증 목적으로만 @angular/fire와 같은 방법을 사용하는 경우 @angular/fire 라이브러리에서 앞서 제안한 것과 동일한 방법을 사용할 수 있습니다.

import { Auth, getAuth, createUserWithEmailAndPassword } from '@angular/fire/auth';
import { deleteApp, initializeApp } from '@angular/fire/app';
import { firebaseConfiguration } from '../config/app.config';   // <-- Your project's configuration here.


const tempApp = initializeApp(firebaseConfiguration, "tempApp");
const tempAppAuth = getAuth(tempApp);
await createUserWithEmailAndPassword(tempAppAuth, email, password)
.then(async (newUser) => {
    resolve( () ==>  {
        // Do something, e.g. add user info to database
    });
})
.catch(error => reject(error))
.finally( () => {
    tempAppAuth.signOut()
    .then( () => deleteApp(tempApp)); 
});

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(...)
}

다음은 Jcabrera의 답변을 Swift 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")
        }

Polymer and Firebase(폴리머 및 파이어베이스)를 사용하는 경우 다음 답변을 참조하십시오. https://stackoverflow.com/a/46698801/1821603

기본적으로 보조 장치를 만듭니다.<firebase-app>현재 사용자에게 영향을 미치지 않고 새 사용자 등록을 처리합니다.

Android 솔루션(Kotlin):

1. API 키, dburl 등을 설정하려면 Firebase Options Builder(!)가 필요하며, 마지막에 build()를 호출하는 것을 잊지 마십시오.

2. FirebaseApp.initializeApp()을 호출하여 보조 인증 변수를 만듭니다.

3.Firebase 인스턴스 가져오기새로 만든 보조 인증을 전달하여 인증하고 원하는 작업을 수행합니다(예: 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()

            }

        }

    }

Android의 경우, 저는 api 키, 애플리케이션 ID 등을 손으로 제공할 필요 없이 단지 그것을 하는 더 간단한 방법을 제안합니다.FirebaseOptions기본 인스턴스의

val firebaseDefaultApp = Firebase.auth.app
val signUpAppName = firebaseDefaultApp.name + "_signUp"

val signUpApp = try {
    FirebaseApp.initializeApp(
        context,
        firebaseDefaultApp.options,
        signUpAppName
    )
} catch (e: IllegalStateException) {
    // IllegalStateException is throw if an app with the same name has already been initialized.
    FirebaseApp.getInstance(signUpAppName)
}

// Here is the instance you can use to sign up without triggering auth state on the default Firebase.auth
val signUpFirebaseAuth = Firebase.auth(signUpApp)

어떻게 사용합니까?

signUpFirebaseAuth
            .createUserWithEmailAndPassword(email, password)
            .addOnSuccessListener {
                // Optional, you can send verification email here if you need

                // As soon as the sign up with sign in is over, we can sign out the current user
                firebaseAuthSignUp.signOut()
            }
            .addOnFailureListener {
                // Log
            }

이 질문에 대한 저의 해결책은 사용자 이름/이메일 및 암호를 정적 클래스에 저장한 다음 새 사용자를 추가하여 새 사용자를 로그아웃하고 관리자 사용자(저장한 ID 패스)로 즉시 로그인하는 것입니다.나에게는 매력적으로 작동합니다 :D

이것은 Kotlin을 위한 버전입니다.

    fun createUser(mail: String, password: String) {
        val opts = FirebaseOptions.fromResource(requireContext())
        if (opts == null) return
        val app = Firebase.initialize(requireContext(), opts, "Secondary")
        FirebaseAuth.getInstance(app)
            .createUserWithEmailAndPassword(mail, password)
            .addOnSuccessListener {
                app.delete()
                doWhateverWithAccount(it)
            }.addOnFailureListener {
                app.delete()
                showException(it)
            }
    }

기본 Firebase 응용 프로그램 인스턴스의 구성을 다른 이름으로 사용합니다.또한 새로 만든 인스턴스는 나중에 삭제되므로 기존 보조 응용 프로그램에 대한 예외 없이 이 인스턴스를 여러 번 호출할 수 있습니다.

파이어베이스 인증 REST API를 사용하여 사용자를 생성해 보십시오.REST API를 통해 Firebase Auth 백엔드를 쿼리할 수 있습니다.새 사용자 만들기, 기존 사용자 로그인 및 이러한 사용자 편집 또는 삭제와 같은 다양한 작업에 사용할 수 있습니다.

https://firebase.google.com/docs/reference/rest/auth#section-create-email-password

언급URL : https://stackoverflow.com/questions/37517208/firebase-kicks-out-current-user

반응형