首页 > 解决方案 > 您使用什么数据类型将字典传递给 httpsCallable 函数?

问题描述

我是服务器端代码的新手,我一直在尝试将数据库文档创建切换到服务器端以创建帐户。下面我包含了我在我的 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,
    });
});

标签: javascriptswiftfirebasegoogle-cloud-firestoregoogle-cloud-functions

解决方案


仔细阅读错误信息。它只是告诉您为新文档的 First_Name 属性提供的值未定义。这只是意味着您没有为应用程序中的那个字段提供值。由于我们无法self.userFN在您的应用中看到 的价值,因此我们并不真正知道这里发生了什么。

我建议在您的客户端应用程序和后端功能上进行一些日志记录,以查看实际发送和接收的数据,以便您可以诊断呼叫是否按您期望的方式发生。


推荐阅读