в реактивном приложении-редуксе я хочу отписаться от нескольких слушателей onSnapshot (5), когда пользователь выходит из системы. Я пытался отписаться от нескольких моих слушателей, но после выхода из системы возникает ошибка:
Вот мое действие по выходу из системы:
export const logoutUser = (uid, role) => {
return (dispatch) => {
onProfileChange(uid, true);
getConversations(uid, true);
getAgenda(uid, role, true)
onAccountChange(uid, true)
return new Promise((resolve, reject) => {
firebase
.auth()
.signOut()
.then(() => {
dispatch({ type: types.RESET_APP });
console.log('Dispatching types.RESET_APP');
resolve();
})
.catch((error) => reject(error.message));
});
};
};
Вот действие onProfileChange
(структура этого действия аналогична остальной, с условным оператором для аргумента отказа от подписки). это, очевидно, находится во внешнем файле, импортированном в компонент и сопоставленном с реквизитами
export const onProfileChange = (uid, isUnsubscribe) => {
return (dispatch) => {
const unsubscribe = firebase.firestore().collection('profiles').doc(uid).onSnapshot((doc) => {
console.log('Profile: ' + JSON.stringify(doc.data()));
dispatch({ type: types.LOAD_PROFILE, payload: doc.data() });
});
if ( typeof isUnsubscribe != "undefined" || isUnsubscribe == true) {
unsubscribe()
}
};
};
В конструкторе моего компонента я вызываю приведенную выше функцию следующим образом:
constructor (props) {
super(props);
props.onAccountChange(props.authUser.uid);
}
, затем это функция внутри того же компонента выполняется при нажатии кнопки:
logout = () => {
this.props
.logoutUser(this.props.authUser.uid, this.props.role)
.then(() => {
this.props.navigation.navigate('Login');
})
.catch((err) => alert(err));
};
РЕДАКТИРОВАТЬ: набор правил Firebase:
service cloud.firestore {
// allow only authenticated users to view database data
match /databases/{database}/documents {
allow read: if request.auth.uid != null
}
// allow only the logged in user to write their own documents
// i.e Account data, Profile data, Messages, User-Conversations
match /databases/{database}/documents {
match /users/{uid} {
allow read, write, update, delete: if request.auth.uid == uid
}
match/users/{uid} {
allow update: if request.auth.uid != null
}
match /profiles/{uid} {
allow write, update, delete: if request.auth.uid == uid
}
// allow reading of all profile data if authenticated
match /profiles/{uid} {
allow read: if request.auth.uid != null
}
match /users/{uid} {
allow read: if request.auth.uid != null
}
match /mostWanted/{docId} {
allow read, update, create: if request.auth.uid != null
}
// Get multiple Docs by single owner (User-Conversations)
match /user-conversations/{docId} {
allow read, delete:
if resource.data.owner == request.auth.uid
}
// Do the same ^ for /messages/{docId}
// => requires 'receiver' data property to integrate
match /messages/{docId} {
allow create, read, update: if request.auth.uid != null
}
// allow read/write of user-convo's if authenticated
match /user-conversations/{docId} {
allow read, write, update: if request.auth.uid != null
}
}
}
Почему я все еще получаю эту ошибку firebase/permission-denied
, если слушатели имеют был отписан? Единственное, о чем я думаю, это установить слушателя состояния аутентификации во всех этих действиях. и когда это изменится, вызовите unSubscribe
reference