AngularJS+GeoFire位置应用部署Firebase报错:无法读取undefined的'myID'属性
Cannot read property 'myID' of undefined错误 你遇到的这个警告,核心问题是key_entered的回调函数里,有代码试图访问某个对象的myID属性,但这个对象是undefined。结合你提到的“生产环境正常、部署Firebase后出问题”,以及代码里关于this.hits缓存的注释,大概率是下面几个原因之一,我给你逐一分析解决办法:
1. 回调里的this指向跑偏了(最常见)
虽然你用了箭头函数来绑定this,但在AngularJS和Firebase的混合环境里,有时候嵌套函数或者异步操作会改变this的指向。比如如果你的回调里嵌套了普通函数,那内部函数的this就不再指向你的组件实例,这时候访问this.myID自然就会报错。
修复方案:
要么把所有嵌套函数都换成箭头函数,要么提前把组件的this缓存到一个变量里(比如self),在回调里用这个变量代替this:
getLocations(radius: number, coords: Array<number>) { console.log(radius, coords); // 先把组件的this存起来 const self = this; this.geoFire.query({ center: coords, radius: radius }) .on('key_entered', (userKey, location, distance) => { // 用self代替this,确保指向组件实例 if (userKey !== self.myID) { // 这里处理你的逻辑,比如更新hits const currentHits = self.hits.value; self.hits.next([...currentHits, { userKey, location, distance }]); } }); }
2. hits行为主体没初始化好
你提到this.hits是个BehaviorSubject,如果在部署Firebase后,这个主体没有在回调触发前完成初始化(比如初始化代码放在了某个异步操作里,回调先执行了),那this.hits就会是undefined,如果你的代码里不小心访问了它的属性,或者操作它时出错,也会触发类似警告。
修复方案:
确保hits在组件初始化的时候就创建好,比如在构造函数里:
constructor() { // 给BehaviorSubject一个默认值,避免初始状态为undefined this.hits = new BehaviorSubject([]); }
同时在回调里先做个检查,确保hits存在再操作:
.on('key_entered', (userKey, location, distance) => { if (!this.hits) return; // 先确认hits已初始化 if (!this.myID) { console.warn('myID还没初始化,跳过这条数据'); return; } if (userKey !== this.myID) { // 处理逻辑 this.hits.next([...this.hits.value, { userKey, location, distance }]); } });
3. GeoFire重复触发回调,缓存里混了无效数据
根据你的注释,this.hits会缓存之前的结果,而GeoFire每次查询都会重新获取数据。部署到Firebase后,可能查询触发的频率更高,或者缓存的结果里出现了undefined的条目,导致你处理这些条目时访问myID报错。
修复方案:
在处理回调数据前,先检查必要的变量是否有效:
.on('key_entered', (userKey, location, distance) => { // 先检查userKey和location是否存在,避免无效数据 if (!userKey || !location) return; // 再检查myID是否已定义 if (!this.myID) { console.warn('myID未定义,跳过当前条目'); return; } if (userKey !== this.myID) { // 处理逻辑 this.hits.next([...this.hits.value, { userKey, location, distance }]); } });
额外的排查小技巧
你可以在Firebase控制台的日志里多打一些调试信息,看看具体哪个变量是undefined,比如在回调里加这些日志:
.on('key_entered', (userKey, location, distance) => { console.log('当前this指向:', this); console.log('myID的值:', this?.myID); console.log('当前获取到的userKey:', userKey); // 后续逻辑 });
这样能快速定位到底是this的问题,还是myID本身没被赋值。
内容的提问来源于stack exchange,提问作者Doyin Olarewaju

