angular - 在将文件保存到存储之后,如何处理与调用在 Firestore 上创建新对象的方法相关的错误情况?
问题描述
我不太喜欢 Angular 和 Firebase,我有以下问题。
我有以下代码来处理用户注册的整个周期。它部分有效,但我有一个问题,我将尝试详细解释(可能是因为我在函数式编程方面仍然遇到一些困难......):
createUser(user, file) {
console.log(user);
if(user.password != user.password_confirmation) {
let passwordError: any = new Object();
passwordError["message"] = "Inserted password and inserted password confirmation are different";
this.eventAuthError.next(passwordError);
}
else {
this.afAuth.auth.createUserWithEmailAndPassword(user.email, user.password)
.then( userCredential => {
this.newUser = user;
console.log(userCredential);
userCredential.user.updateProfile( {
displayName: user.firstName + ' ' + user.lastName
});
this.uploadFileIntoFirebaseStore(file);
this.insertUserData(userCredential, this.downloadURL)
.then(() => {
this.router.navigate(['/home']);
});
})
.catch( error => {
console.log(error);
console.log(typeof error);
this.eventAuthError.next(error); // Emit the event passing the error object
});
}
}
uploadFileIntoFirebaseStore(fileToBeUploaded) {
var n = Date.now();
const filePath = `user_avatar/${n}`;
const fileRef = this.storage.ref(filePath);
const task = this.storage.upload(`user_avatar/${n}`, fileToBeUploaded);
task
.snapshotChanges()
.pipe(
finalize(() => {
this.downloadURL = fileRef.getDownloadURL();
this.downloadURL.subscribe(url => {
if (url) {
this.fb = url;
}
console.log(this.fb);
});
})
)
.subscribe(url => {
if (url) {
console.log(url);
}
});
return this.fb
}
insertUserData(userCredential: firebase.auth.UserCredential, userAvatar) {
let userObg = {
name: this.newUser.firstName,
surname: this.newUser.lastName,
complete_name: this.newUser.firstName + " " + this.newUser.lastName,
email: this.newUser.email,
role: this.newUser.ruolo_utente,
avatar: userAvatar
};
console.log("USER OBJECT: ", userObg);
return this.db.doc(`Users/${userCredential.user.uid}`).set(userObg);
}
基本上它做了以下事情:
createUser()
获取一个必须保存到 FireStore 集合中的用户对象和一个文件参数,该参数是必须保存到 Firebase 存储中的图像。首先,它
createUserWithEmailAndPassword()
使用用户名和密码调用创建一个新用户到 Firebase 身份验证服务(它工作正常)。如果正确创建了用户,它会进入then()并调用
uploadFileIntoFirebaseStore()
用于将图像文件上传到 Firebase 存储的方法。然后它调用
insertUserData()
创建与当前用户相关的新对象并将其保存到 FireStore 的方法。
我的问题发生在第 3 点和第 4 点之间。详细地说,文件已正确保存到 Firebase 存储中,但在我看来这是一个异步任务,因此需要一些时间才能将与此文件相关的 URL 返回到 Firebase 存储中。这需要时间,但与此同时insertUserData()
启动了,所以这里这个 URL 字段(我必须保存在我的对象中)是未定义的。
什么是等到文件 URL 被“返回”的聪明方法?也许我不必返回任何东西,但一件好事是在检索 URL 之后将调用insertUserData()
(插入 FireStore)放入方法中,这里:uploadFileIntoFirebaseStore()
this.downloadURL.subscribe(url => {
if (url) {
this.fb = url;
// I PUT THE CALL TO HERE
}
console.log(this.fb);
});
什么是解决这个问题的聪明方法?
解决方案
您需要.pipe()
您的流媒体,否则您将永远无法同步它们。
uploadFileIntoFirebaseStore
应该return
上传流:
return this.storage.upload(`user_avatar/${n}`, fileToBeUploaded)
.snapshotChanges()
.pipe(switchMap(() => fileRef.getDownloadURL());
然后,在你的createUser
你可以使用它:
this.uploadFileIntoFirebaseStore(file).subscribe(downloadURL =>
this.insertUserData(userCredential, downloadURL)
.then(() => {
this.router.navigate(['/home']);
});
);
推荐阅读
- c++ - 带有限定符的函数类型 typedef 的用例
- apache-spark - 如何从 spark 建立与 Cassandra 的区域/dc 感知连接?
- apache - Moodle php_extension intl
- c# - 在 WPF 中使用 Caliburn Micro 导入构造函数 MEF
- azure - 有没有办法将功能应用超时阈值从 30 分钟(默认)增加到 2 小时?我们在应用服务计划中
- reactjs - 如何折叠其他展开的 core-ui 侧边栏项目
- elasticsearch - Elasticsearch 转错结果?
- asp.net-core - 如何使用 Jetbrains Rider 调试(.net 核心项目)配置 Stackify 前缀
- heroku - Heroku 应用程序在 H12 错误后何时开始工作?
- activemq - ResourceAdapter 已设置 | 带有活动 MQ 的 JBoss 5.2