Я добавил функцию, как вы упомянули, но когда я вхожу в систему, она показывает эту ошибку:
TypeError: Cannot set property 'photo' of undefined
at feed.page.ts:32
at auth.esm.js:326
at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invoke (zone.js:391)
at Object.onInvoke (core.js:17299)
at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invoke (zone.js:390)
at Zone.push../node_modules/zone.js/dist/zone.js.Zone.run (zone.js:150)
at zone.js:889
at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:423)
at Object.onInvokeTask (core.js:17290)
at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:422)
at resolvePromise (zone.js:831)
at zone.js:896
at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:423)
at Object.onInvokeTask (core.js:17290)
at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:422)
at Zone.push../node_modules/zone.js/dist/zone.js.Zone.runTask (zone.js:195)
at drainMicroTaskQueue (zone.js:601)
at push../node_modules/zone.js/dist/zone.js.ZoneTask.invokeTask (zone.js:502)
at ZoneTask.invoke (zone.js:487)
at timer (zone.js:2281)
Если обновить страницу, то пишет:
getEvents() is not a function
Изменения, которые я сделал, и все еще получаю ошибку. Это странно, потому что, когда я вхожу в систему и перенаправляюсь на FeedPage, я получаю фотографию с ошибкой undefined, если я обновляю, я получаю, что getEvents() не является функцией. ngModel и показать фото на аватаре.
events: any[] = [];
likes: any[] = [];
pageSize = 10;
cursor: any; // can be declared as DocumentSnapshot
infiniteEvent: any;
state: any;
private photo = '';
// tslint:disable-next-line: max-line-length
constructor(public navCtrl: NavController, private loadingCtrl: LoadingController, private toastCtrl: ToastController, private http: HttpClient, public actionSheetCtrl: ActionSheetController, public alertCtrl: AlertController, public modalCtrl: ModalController, public popoverCtrl: PopoverController) {
firebase.auth().onAuthStateChanged(function (user) {
if (user) {
this.photo = user.photoURL;
this.getEvents();
} else {
console.info('Not authenticated');
// No user is signed in.
}
});
}
public async getEvents() {
const loading = await this.loadingCtrl.create({
message: 'Loading events...'
});
loading.present();
const query = firebase.firestore().collection('events').orderBy('created', 'desc').limit(this.pageSize);
query.onSnapshot((snapshot) => {
const changedDocs = snapshot.docChanges();
changedDocs.forEach((change) => {
if (change.type === 'added') {
// TODO
}
if (change.type === 'modified') {
for (let i = 0; i < this.events.length; i++) {
if (this.events[i].id == change.doc.id) {
this.events[i] = change.doc;
}
}
}
if (change.type === 'removed') {
// TODO
}
})
})
query.get()
.then((events) => {
events.forEach((event) => {
this.events.push(event);
});
loading.dismiss();
if (events.size == 0) {
this.cursor = 0;
} else {
this.cursor = this.events[this.events.length - 1]; // the last index of the collection
}
console.info(this.events);
}).catch((err) => {
console.info(err);
});
}
Я написал сообщение в блоге о лучших практиках для реагировать на изменения в текущем пользователе.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Похоже, что firebase.auth().currentUser не установлен, когда работает ваш Feed.ts. Это ожидаемо, так как клиенту может потребоваться проверить на сервере, действителен ли токен, что является асинхронной операцией.
В подобных случаях всегда используйте прослушиватель onAuthStateChanged, как показано в первом фрагменте документации на получение текущего зарегистрированного пользователя.
Итак, что-то вроде:
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
// User is signed in.
... code that uses the user's properties
} else {
// No user is signed in.
}
});
Редактировать
Ваша новая ошибка getEvents() is not a function вызвана тем, что this имеет другое значение внутри функции обратного вызова, объявленной как function(). Самым простым решением здесь является использование нотации =>, которая поддерживает значение this внутри функции:
firebase.auth().onAuthStateChanged((user) => {
if (user) {
this.photo = user.photoURL;
this.getEvents();
} else {
console.info('Not authenticated');
// No user is signed in.
}
});
Обратите внимание, что остальная часть вашего кода уже использует нотацию =>, что заставляет меня подозревать, что вы еще не так долго писали JavaScript. Я настоятельно рекомендую пройти руководство по функции обратного вызова в JavaScript, так как это сэкономит вам много времени и вопросов) в будущем.
Я добавил эту функцию, но где именно я должен ее добавить? В конструкторе или после него? Такая же проблема возникла
Вы бы добавили его везде, где вам нужен текущий пользователь, и не можете быть уверены, что пользователь уже вошел в систему (что почти везде).
Проблема в том, что я не могу добавить его куда угодно, потому что есть некоторые ошибки отладки. Я должен добавить перед объявлениями переменных, потому что код не может найти photoUrl. Можете ли вы показать мне, где это реализовать, в примере?
Любой код, которому требуется информация о текущем вошедшем в систему пользователе, должен быть в вашем обратном вызове onAuthStateChanged.
Пожалуйста, отредактируйте свой вопрос, чтобы также показать код, который у вас теперь есть, на основе моего ответа, а также точное сообщение об ошибке + трассировку стека, которую вы получаете.
Есть ли какой-либо механизм, подобный auth().getCurrentUser() : Promise<User | null>, который будет приостанавливаться до тех пор, пока токен не будет проверен на сервере, или немедленно вернется, если он уже проверен? Я хочу показывать индикатор выполнения, пока не буду уверен, что пользователь вошел в систему или нет. auth().onAuthStateChanged() просто не вписывается в этот сценарий.
Ничего не встроено, но вы можете довольно легко свернуть awaitAuthenticatedUser() с помощью onAuthStateChanged и обещания. Попробуйте, и если вам трудно заставить его работать, опубликуйте новый вопрос с кодом, который вы пробовали сами.
О, теперь я полностью понимаю, и, как вы и сказали, я не писал здесь слишком много кода javascript, так как я смотрел некоторые уроки и добавлял некоторые другие вещи. Я исправил проблему, а также вы помогли мне понять простую, но важную вещь. Большое спасибо за ваше время.
«Изменения, которые я внес, но все еще получаю сообщение об ошибке». Это совершенно другая ошибка. Я ответил и на него ниже, но, пожалуйста, ограничьтесь одной проблемой на пост. Если сообщение об ошибке существенно отличается от предыдущего, скорее всего, это новая проблема (в том же варианте использования). Взгляните на как создать минимальный, полный, проверяемый пример, чтобы узнать, как локализовать проблему.