我是服务器端代码的新手,我一直在尝试将数据库文档创建切换到服务器端进行帐户创建。下面我包含了我在xcode项目中定义的函数以及服务器端函数。调用函数后,我收到一个错误,说
未处理的错误错误:参数"的值;数据";不是有效的Firestore文档。不能使用";未定义的";作为Firestore值(在字段"First_Name"中找到(。如果要忽略未定义的值,请启用
ignoreUndefinedProperties
。
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,
});
});
仔细阅读错误消息。它只是告诉您,您为新文档的First_Name属性提供的值是未定义的。这只是意味着你没有为应用程序中的那个字段提供值。由于我们在您的应用程序中看不到self.userFN
的值,我们真的不知道这里发生了什么。
我建议您在客户端应用程序和后端功能上进行一些登录,以查看实际发送和接收的数据,这样您就可以诊断呼叫是否按预期方式进行。