AuthStateChanged에서 Firebase Android가 두 번 호출되었습니다.
새로운 Firebase SDK로 작업을 시작했습니다.
사용자 로그인을 할 때 AuthStateChanged 메서드가 동일한 상태로 두 번 호출됩니다(사용자 로그인 등).
AuthStateListener를 Firebase에 한 번만 추가합니다.인증 참조.
도와드릴까요?
네, 그리고 이것은 매우 짜증나는 일입니다.등록 전화 때문입니다.뿐만 아니라 AuthStateChanged는 여러 주에서 여러 번 호출되며 어떤 상태인지 알 수 없습니다.
설명서에는 다음이 나와 있습니다.
onAuthStateChanged(파이어베이스)인증)
이 메서드는 인증 상태가 변경될 때 UI 스레드에서 호출됩니다.
수신기가 등록된 직후
사용자가 로그인한 경우
현재 사용자가 로그아웃된 경우
현재 사용자가 변경될 때
현재 사용자 토큰이 변경된 경우
다음은 현재 상태를 확인하기 위한 몇 가지 팁입니다.
- 등록 호출: 플래그가 있는 첫 번째 호출을 건너뜁니다.
- 사용자 로그인: 매개 변수의 사용자가 != null입니다.
- 사용자가 로그아웃했습니다. 매개 변수의 사용자가 == null입니다.
- 현재 사용자 변경 사항: 매개 변수의 사용자는 != null이고 마지막 사용자 ID는 != 사용자 ID입니다.
- 사용자 토큰 새로 고침: 매개 변수의 사용자는 != null이고 마지막 사용자 ID는 매개 변수의 == 사용자 ID입니다.
이 청취자는 엉망이고 매우 버그가 많습니다.소방본부에서 조사해야 합니다.
여기에 제공된 다른 답변이 도움이 될 수 있지만 플래그를 관리하는 것은 번거롭고 오류가 발생하기 쉽습니다.
저는 짧은 시간 내에 그 행사를 발표하는 것을 선호합니다.사용자가 로그인한 후 200ms 내에 로그아웃하는 것은 매우 가능성이 낮거나 불가능할 수도 있습니다.
TLDR
디바운스는 이벤트를 처리하기 전에 미리 정의된 기간 내에 동일한 이벤트가 다시 실행되는지 여부를 확인하기 위해 기다리는 것을 의미합니다.그러면 타이머를 재설정하고 다시 기다립니다.그렇지 않으면 이벤트를 처리합니다.
이것은 Android의 질문으로, 제 분야는 아니지만, Android가 작업에 도움이 될 수 있는 도구를 제공한다고 확신합니다.그렇지 않다면 간단한 타이머로 만들 수 있습니다.
Javascript 구현은 다음과 같습니다.
var debounceTimeout;
const DebounceDueTime = 200; // 200ms
function onAuthStateChanged(auth)
{
if (debounceTimeout)
clearTimeout(debounceTimeout);
debounceTimeout = setTimeout(() =>
{
debounceTimeout = null;
handleAuthStateChanged(auth);
}, DebounceDueTime);
}
function handleAuthStateChanged(auth)
{
// ... process event
}
해결 방법은 전역적으로 선언된 부울을 사용하여 onAuthStateChanged가 이전에 호출된 경우 플래그를 지정하는 것입니다.
private Boolean authFlag = false;
mAuthListener = new FirebaseAuth.AuthStateListener() {
@Override
public void onAuthStateChanged(@NonNull final FirebaseAuth firebaseAuth) {
if (firebaseAuth.getCurrentUser() != null) {
if(authFlag== false) {
// Task to perform once
authFlag=true;
}
}
}
};
일반적으로 수신기를 추가하기 전에 UI를 설정하고 인증 상태가 변경될 때마다 설정을 반복합니다(초기 이중 호출은 피함).제 해결책은 부울 플래그 솔루션을 향상시키고 마지막 사용자의 uid(토큰이 아님)를 추적하는 것입니다. 이는 null일 수 있습니다.
private FirebaseAuth firebaseAuth;
private String lastUid; // keeps track of login status and changes thereof
Create에서 시작 시 수신기를 추가하기 전에 인증 인스턴스를 가져오고 그에 따라 UI를 설정합니다.
@Override
protected void onCreate(Bundle savedInstanceState){
...
firebaseAuth = FirebaseAuth.getInstance();
getUserSetUI();
...
}
where getUserSet인증 인스턴스에 따라 UI가 lastUid를 설정합니다.
private void getUserSetUI(){
lastUid = (firebaseAuth == null || firebaseAuth.getCurrentUser() == null) ?
null : firebaseAuth.getUid();
setUI(!(lastUid == null));
}
수신기는 상태가 실제로 변경되었는지 확인합니다.
@Override
public void onAuthStateChanged(@NonNull FirebaseAuth auth){
String uid = auth.getUid(); // could be null
if( (uid == null && lastUid != null) || // loggedout
(uid != null && lastUid == null) || // loggedin
(uid != null && lastUid != null && // switched accounts (unlikely)
!uid.equals(lastUid))){
getUserSetUI();
}
}
if (authStateListener == null) {
authStateListener = new FirebaseAuth.AuthStateListener() {
@Override
public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
if (firebaseAuth.getCurrentUser() == null) {
//Do anything here which needs to be done after signout is complete
FirebaseAuth.getInstance().removeAuthStateListener(this);
Log.d(TAG_, "logout");
finish();
} else {
}
}
};
}
FirebaseAuth.getInstance().removeAuthStateListener(이)를 호출해야 합니다.
try{
FirebaseAuth.getInstance().signOut();
FirebaseInstanceId.getInstance().deleteInstanceId();
}catch (Exception ex){
ex.printStackTrace();
}
사용자가 gmail에서 로그아웃할 때 사용자도 파이어베이스에서 로그아웃해야 합니다.이것이 제가 이 문제를 해결한 방법입니다.
언급URL : https://stackoverflow.com/questions/37673616/firebase-android-onauthstatechanged-called-twice
'programing' 카테고리의 다른 글
SQL Server - 큰 스크립트 파일 실행 (0) | 2023.07.10 |
---|---|
Git Push 오류: 체크아웃된 분기 업데이트 거부 (0) | 2023.07.10 |
쿠키에 암호를 저장하는 것이 안전합니까? (0) | 2023.07.10 |
Oracle 상수를 단일 테이블로 병합 (0) | 2023.07.10 |
Spring Boot 테스트에서 트랜잭션 커밋을 강제하는 방법은 무엇입니까? (0) | 2023.07.10 |