Angular结合Firebase推送对象时出现TS2304找不到db错误该如何解决
报错根因
「找不到名称db」是典型的TS作用域问题:
- 你在构造函数中写的
db: AngularFireDatabase只是构造函数的局部形参,可访问范围完全局限在构造函数的大括号内部,类中独立定义的addCourse方法无法获取这个变量,自然会触发未定义报错。
修正方案
1. 让db实例可以在类的所有方法中访问
Angular的依赖注入机制支持一种简写语法:在构造函数的注入参数前加上private/public这类访问修饰符,框架会自动把注入的服务实例挂载到当前类的this上下文上,不需要手动赋值,类里任意方法都能通过this.db访问到这个实例。
2. 修正Firebase写入逻辑
原代码里的写入代码本身也存在逻辑偏差:
- 如果你的需求是推送对象让Firebase自动生成唯一不重复的存储key,应该使用
push方法,而不是set——set会强制覆盖指定路径的全部内容,适合固定路径的写入场景;push才是数据库列表类的标准推送操作,会自动生成不重复的ID避免key冲突。
修正后的完整代码
component.ts
import { Component } from '@angular/core'; import { AngularFireDatabase } from 'angularfire2/database'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'], }) export class AppComponent { title = 'FirebaseDemo'; courses$: any[]; // 构造函数参数前加private,自动成为类成员 constructor(private db: AngularFireDatabase) { // 读取课程列表的逻辑正常执行 db.list('/course') .valueChanges() .subscribe((res) => { this.courses$ = res; console.log(this.courses$); }); } addCourse(value: string) { // 通过this.db访问注入的Firebase实例 // 自动生成key的推送操作 this.db.list('/course').push(value); // 如果确实需要固定使用key=4写入,可以用set // this.db.list('/course').set('4', value); } }
component.html
<h3>Adding an object</h3> <!-- 注意原代码的问题:直接把#course元素引用传给addCourse,实际拿到的是DOM节点不是输入值 这里修正为传递输入框的value属性,同时保留回车触发的逻辑 --> <input type="text" (keyup.enter)="addCourse(courseInput.value)" #courseInput>
补充说明
如果不想用构造函数加修饰符的简写,也可以手动声明类成员后在构造函数中赋值,效果完全一致,只是代码稍冗余:
// 手动声明成员的写法 private db: AngularFireDatabase; constructor(db: AngularFireDatabase) { // 手动把构造函数的局部参数赋值给类成员 this.db = db; // 其他读取逻辑 } // 类方法里同样通过this.db访问实例
内容的提问来源于stack exchange,提问作者Kartik Dolas
相关产品推荐
相关产品推荐

