Javascript 您使用什么数据类型将字典传递到HttpScalable函数?
我不熟悉服务器端代码,我一直在尝试将数据库文档创建切换到服务器端进行帐户创建。下面我介绍了我在xcode项目中定义的函数以及服务器端函数。调用函数后,我得到一个错误 未处理的错误:参数“data”的值不是有效的Firestore文档。无法将“undefined”用作Firestore值(在字段“First_Name”中找到)。如果要忽略未定义的值,请启用Javascript 您使用什么数据类型将字典传递到HttpScalable函数?,javascript,swift,firebase,google-cloud-firestore,google-cloud-functions,Javascript,Swift,Firebase,Google Cloud Firestore,Google Cloud Functions,我不熟悉服务器端代码,我一直在尝试将数据库文档创建切换到服务器端进行帐户创建。下面我介绍了我在xcode项目中定义的函数以及服务器端函数。调用函数后,我得到一个错误 未处理的错误:参数“data”的值不是有效的Firestore文档。无法将“undefined”用作Firestore值(在字段“First_Name”中找到)。如果要忽略未定义的值,请启用ignoreUndefinedProperties 仔细阅读错误消息。它只是告诉您,您为新文档的First_Name属性提供的值未定义。这只意味
ignoreUndefinedProperties
仔细阅读错误消息。它只是告诉您,您为新文档的First_Name属性提供的值未定义。这只意味着你没有为你的应用程序中的一个字段提供值。因为我们无法在你的应用程序中看到
self.userFN
的价值,所以我们不知道这里到底发生了什么
我建议您在客户端应用程序和后端功能上进行一些日志记录,以查看实际发送和接收的数据,这样您就可以诊断呼叫是否按预期方式进行。所有字段的值都正确存储在我的项目中,并且可以在客户端访问。我已经包含了上面描述的代码。我在这里没有看到任何有用的调试信息。请添加一些日志,显示此代码的执行方式以及客户端和后端上使用的值,以便我们可以看到发生了什么。我在上面包含了更多的代码。在我的代码中,我将用户提供的值存储在字典中,并最终使用字典生成RegistrationModel类的实例。我在typescript的底部包含了服务器端代码,我在调试器中运行了该代码,并且能够看到rm变量中正确存储的值
class RA_2ViewController: UIViewController, UITextFieldDelegate {
@IBOutlet weak var fNameField: UITextField!
@IBOutlet weak var lNameField: UITextField!
@IBOutlet weak var emailField: UITextField!
@IBOutlet weak var pNumberField: UITextField!
@IBOutlet weak var countryField: UITextField!
@IBOutlet weak var cityField: UITextField!
@IBAction func nextButtonPressed(_ sender: Any) {
// Check Fields
if let error = self.validateFields() {
showError(error)
}else{
userInfo.updateValue(emailField.text!, forKey: "userEmail")
userInfo.updateValue(fNameField.text!, forKey: "userFirstName")
userInfo.updateValue(lNameField.text!, forKey: "userLastName")
userInfo.updateValue(pNumberField.text!, forKey: "userPhoneNumber")
userInfo.updateValue(countryField.text!, forKey: "userCountry")
userInfo.updateValue(cityField.text!, forKey: "userCity")
performSegue(withIdentifier: "avatar", sender: self)
}
}
}
class PasswordSetUpViewController:UIViewController{
@IBAction func nextButtonPressed(_ sender: Any) {
if passwordField.text != nil && passwordConfirmationField.text != nil {
if passwordField.text! != passwordConfirmationField.text! {
let message = "Passwords must match"
showError(message)
return
}
userInfo.updateValue(passwordField.text!, forKey: "userPassword")
let rm = registrationModel(userInfo)
if userInfo["accountType"] == "Advertiser"{
rm.createAdvertiserUser(rm.userEmail!, rm.userPassword!)
}
if userInfo["accountType"] == "Influencer"{
rm.createBloggerUser(rm.userEmail!, rm.userPassword!)
}
if textHelpers.validatePassword(passwordField.text!) == false {
let message = "Invalid Password, ensure that password meets the required criteria"
showError(message)
return
}
}
if passwordField.text == "" || passwordConfirmationField.text == "" {
let message = "Please fill in both fields"
showError(message)
return
}
performSegue(withIdentifier: "numberConfirmationScreen", sender: self)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.destination is NumberConfirmationViewController {
let vc = segue.destination as? NumberConfirmationViewController
vc?.userInfo = self.userInfo
}
}
}
class registrationModel {
var userFN:String?
var userLN:String?
var userEmail:String?
var userPassword:String?
var userPhoneNum:String?
var userCountry:String?
var userCity:String?
var userDOB:String?
var userContentType:String?
var userCompanyName:String?
var subscriptionType:String?
var accountType:String?
var userAvatar:UIImage?
init(_ userEntries: [String:String]) {
accountType = userEntries["accountType"]
userFN = userEntries["userFirstName"]
userLN = userEntries["userLastName"]
userEmail = userEntries["userEmail"]
userPhoneNum = userEntries["userPhoneNumber"]
userPassword = userEntries["userPassword"]
userCountry = userEntries["userCountry"]
userCity = userEntries["userCity"]
subscriptionType = userEntries["subscriptionType"]
userDOB = userEntries["userDOB"]
}
func createAdvertiserUser(_ email:String, _ password:String){
let advUser = AdvertiserUser(Account_Type: self.accountType!, First_Name: self.userFN!, Last_Name: self.userLN!, Phone_Number: self.userPhoneNum!, Country: self.userCountry!, Subscription_Type: self.subscriptionType!)
let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted
let data = try! encoder.encode(advUser)
let valid = JSONSerialization.isValidJSONObject(data)
Auth.auth().createUser(withEmail: email, password: password) { authResult, error in
var functions = Functions.functions()
functions.httpsCallable("createAdvertiserUserData").call(data) { (result,error) in
if let error = error as NSError? {
if error.domain == FunctionsErrorDomain {
let message = error.localizedDescription
}
// ...
}
}
if error != nil{
// Show error
} else {
// Successfull user creation
}
}
}
struct AdvertiserUser: Codable{
var Account_Type: String
var First_Name: String
var Last_Name: String
var Phone_Number: String
var Country: String
var Subscription_Type: String
}
struct BloggerUser: Codable{
var Account_Type: String
var First_Name: String
var Last_Name: String
var Phone_Number: String
var Date_of_Birth: String
}
import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';
admin.initializeApp();
exports.createAdvertiserUserData = functions.https.onCall((data,context) => {
if(!context.auth){
throw new functions.https.HttpsError('unauthenticated', 'user must sign in');
}
return admin.firestore().collection('users/advertiserUsers/userAccounts').doc(context.auth.uid).set({
Account_Type: data.Account_Type,
First_Name: data.First_Name,
Last_Name: data.Last_Name,
Phone_Number: data.Phone_Number,
Country: data.Country,
Subscription_Type: data.Subscription_Type,
});
});