当前位置: 首页 > 知识库问答 >
问题:

Firebase和SwiftUI保存配置文件数据

申屠泳
2023-03-14

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

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

我的问题是:

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

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

下面是上图屏幕的代码:

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个答案

陆翰藻
2023-03-14

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相关联(如上文所述)。

 类似资料:
  • 问题内容: 我正在使用selenium和Firefox从互联网下载文件。当我尝试下载文件时,我得到的下载框询问我是否要保存文件或“打开方式”。我想保存文件,但不是自动保存(想重命名文件名),我希望浏览器会问我保存文件的位置。在firefox设置下,“始终询问在哪里保存文件”这个选项仍然被选中。.当我使用selenium运行脚本时,它不是在问我并保存文件。如何设置Firefox配置文件来执行此操作?

  • 我正在使用AngularFire2成功将图像上传到Firebase Storage。 我有以下上传代码。 我想解决几个问题。 如何设置文件大小限制?这意味着我希望用户能够上传小于10mb的文件。 如何限制文件编号?这意味着我希望一个用户只能上传3个文件。 如果没有firebase服务器规模的解决方案,请推荐一些客户端规模的解决方案。 谢谢

  • Im使用firebase,由于某些原因,我的代码没有推送数据,并且Im没有在firebase URL中看到数据。我的密码是这样的 我得到警报“保存”,但我无法在firebase URL中找到数据。 此外,为Firebase中的每个url提供的API键有什么用途。 更新:这种情况发生在IE10中。在其他浏览器中,它工作得很好

  • 除非设置了主密码,否则压缩配置文件里保存的密码没有安全地加密,并且可以被任何能访问 您电脑的人读取。您可以输入主密码来加密保存在注册表里的密码数据,并保护它免遭未经授权 的访问。此后,您需要在密码提示对话框里输入主密码,才能访问此压缩配置文件。 您可以使用与密码管理器里相同的作为主密码,或者选择不同的密码。您甚至可以为不同的 压缩配置文件指定不同的主密码,尽管这样可能不便于使用。 一旦输入,主密码

  • 我正在尝试将Firebase与我的react应用程序一起使用。 我有一个配置文件如下: 当我尝试此操作时,会出现一个错误,显示: FIREBASE致命错误:无法确定FIREBASE数据库URL。在调用firebase时,请确保包含databaseURL选项。初始化app()。 我不能理解这个错误,因为我在初始化应用程序的调用中包含了配置。配置包括数据库URL。 如何初始化数据库?

  • 我想将一个文件保存在与应用程序jar文件所在位置相同的文件夹中。我正试图通过以下方式实现这一点: 如果我从Intellij运行项目,返回的路径是,如果我从命令行运行它,返回的路径是。这是应该发生的吗?另外,如何才能将jar路径仅返回到?