提问者:小点点

Firebase和SwiftUI保存配置文件数据


我是SwiftUI和Firebase的新手,正在尝试创建一个预算应用程序。我无法保存用户数据。我使用的是SwiftUI(不是Storyboard),我还有AppDelegate和SceneDelegate。

应用程序的工作方式是要求用户创建配置文件(电子邮件和密码),然后在FireBase中创建用户。然后,它将用户重定向到需要以下数据的第二个屏幕(见图):

我的问题是:

  • 如何将照片上载到FireBase?
  • 如何将照片和其他数据(年龄、城市等)与创建的用户相关联?

我正在网上搜索一个解决方案已经有几天了,但是网上的所有东西要么是使用Storyboard要么是很旧的Swift版本。此外,我已经创建了用户,但我不知道如何将屏幕上的数据与创建的用户关联起来。

下面是上图屏幕的代码:

struct RegistrationProfileDataView: View {

//@Binding var show : Bool
@State var firstName = ""
@State var lastName = ""
@State var age = ""
@State var location = ""
@State var picker = false
@State var loading = false
@State var imagedata : Data = .init(count: 0)
@State var alert = false

var body: some View {
    VStack(alignment: .leading) {
        Group {
            Group {
                Text("Welcome")
                    .font(/*@START_MENU_TOKEN@*/.title/*@END_MENU_TOKEN@*/)
                Text("Please finish your registration")
                Button(action: {
                    self.picker.toggle()
                }) {
                    if self.imagedata.count == 0 {
                        Image("ChangeProfPhoto").resizable().frame(width: 109, height: 109)
                    }
                    else {
                        Image(uiImage: UIImage(data: self.imagedata)!).resizable().renderingMode(.original).frame(width: 109, height: 109).clipShape(Circle())
                    }
                }
                .padding(.bottom, 20)
                .padding(.top, 20)
            }
            .padding(.leading, 25)
            TextField("First Name", text: self.$firstName)
                .padding(.leading, 20)
                .frame(minWidth: 0, maxWidth: .infinity)
                .frame(height: 45.0)
                .overlay(Capsule().stroke(Color.lightGray, lineWidth: 1))
                .padding(.horizontal, 25)
            TextField("Last Name", text: self.$lastName)
                .padding(.leading, 20)
                .frame(minWidth: 0, maxWidth: .infinity)
                .frame(height: 45.0)
                .overlay(Capsule().stroke(Color.lightGray, lineWidth: 1))
                .padding(.horizontal, 25)
            TextField("Age", text: self.$age)
                .padding(.leading, 20)
                .frame(minWidth: 0, maxWidth: .infinity)
                .frame(height: 45.0)
                .overlay(Capsule().stroke(Color.lightGray, lineWidth: 1))
                .padding(.horizontal, 25)
            TextField("City", text: self.$location)
                .padding(.leading, 20)
                .frame(minWidth: 0, maxWidth: .infinity)
                .frame(height: 45.0)
                .overlay(Capsule().stroke(Color.lightGray, lineWidth: 1))
                .padding(.horizontal, 25)
            Button(action: /*@START_MENU_TOKEN@*//*@PLACEHOLDER=Action@*/{}/*@END_MENU_TOKEN@*/) {
                Text("Link a Bank Account")
            }
            .frame(minWidth: 0, maxWidth: .infinity)
            .frame(height: 45.0)
            .background(Capsule().fill(Color.lightGray))
            .padding(.horizontal, 25.0)
            .padding(.bottom, 15.0)
        }
        Spacer()
        Group {
            Button(action: /*@START_MENU_TOKEN@*//*@PLACEHOLDER=Action@*/{}/*@END_MENU_TOKEN@*/) {
                Text("Finish")
                    .foregroundColor(.white)
                    .padding()
            }
            .frame(minWidth: 0, maxWidth: .infinity)
            .frame(height: 45.0)
            .background(Capsule().fill(Color.blue))
            .padding(.horizontal, 25.0)
            .padding(.bottom, 15.0)
            .shadow(color: ColorManager.blueButton.opacity(0.2), radius: 10, x: 2.0, y: 2.0)
        }
    }
}

}


共1个答案

匿名用户

Firebase文档非常好,都是现代的Swift代码。它并不真正依赖UI代码(SwiftUI或Storyboards)。

关于SwiftUI,一般来说,您可能希望在视图之外进行网络调用,可能是在ObservableObject中:

class FirebaseManager : ObservableObject {
  func uploadImage(imageData: Data) {
    //do upload
  }
}

您可以通过执行以下操作将其存储在视图中:

@StateObject private var firebaseManager = FirebaseManager()

要上传一个映像,您可以执行如下操作(这几乎直接取自Firebase文档--https://Firebase.google.com/docs/storage/ios/upload-files):

// Create a reference to the file you want to upload
let profileImageRef = storageRef.child("images/\(userID)/rivers.jpg")

// Upload the file to the path "images/rivers.jpg"
let uploadTask = profileImageRef.putData(data, metadata: nil) { (metadata, error) in
  guard let metadata = metadata else {
    // Uh-oh, an error occurred!
    return
  }
  // Metadata contains file metadata such as size, content-type.
  let size = metadata.size
  // You can also access to download URL after upload.
  profileImageRef.downloadURL { (url, error) in
    guard let downloadURL = url else {
      // Uh-oh, an error occurred!
      return
    }
  }
}

请注意,在第一行中,我使用了userid--您可以通过执行以下操作获得对登录用户的引用:

guard let userID = Auth.auth().currentUser?.uid else {
  return
}

最后,关于“如何将照片和其他数据(年龄、城市等)关联到创建的用户”的问题,您需要选择Firestore或Realtime Database。在现代Swift的https://firebase.google.com/docs中都有很好的文档。

firebaseManager中创建一个函数来上传数据,并确保将其与配置文件图像的用户ID相关联(如上文所述)。