chatroom聊天从firestore注销用户
源码:
LoginView:
//
// LoginView.swift
// LuJunChatDemo
//
// Created by lujun on 2022/4/17.
//
import SwiftUI
struct LoginView: View {
let didCompleteLoginProecess: () -> ()
@State var isLoginMode = false
@State var email = ""
@State var password = ""
@State var shouldShowImagePicker = false
var body: some View {
NavigationView {
ScrollView {
VStack(spacing: 16) {
Picker(selection: $isLoginMode, label: Text("Picker here")) {
Text("Login")
.tag(true)
Text("Create Account")
.tag(false)
}.pickerStyle(SegmentedPickerStyle())
if !isLoginMode {
Button {
shouldShowImagePicker.toggle()
} label: {
VStack {
if let image = self.image {
Image(uiImage: image)
.resizable()
.scaledToFill()
.frame(width: 128, height: 128)
.cornerRadius(64)
} else {
Image(systemName: "person.fill")
.font(.system(size: 64))
.padding()
.foregroundColor(Color(.label))
}
}
.overlay(RoundedRectangle(cornerRadius: 64)
.stroke(Color.black, lineWidth: 3)
)
}
}
Group {
TextField("Email", text: $email)
.keyboardType(.emailAddress)
.autocapitalization(.none)
SecureField("Password", text: $password)
}
.padding(12)
.background(Color.white)
Button {
handleAction()
} label: {
HStack {
Spacer()
Text(isLoginMode ? "Log In" : "Create Account")
.foregroundColor(.white)
.padding(.vertical, 10)
.font(.system(size: 14, weight: .semibold))
Spacer()
}.background(Color.blue)
}
Text(self.loginStatusMessage)
.foregroundColor(.red)
}
.padding()
}
.navigationTitle(isLoginMode ? "Log In" : "Create Account")
.background(Color(.init(white: 0, alpha: 0.05))
.ignoresSafeArea())
}
.navigationViewStyle(StackNavigationViewStyle())
.fullScreenCover(isPresented: $shouldShowImagePicker, onDismiss: nil) {
ImagePicker(image: $image)
.ignoresSafeArea()
}
}
@State var image: UIImage?
private func handleAction() {
if isLoginMode {
// print("Should log into Firebase with existing credentials")
loginUser()
} else {
createNewAccount()
// print("Register a new account inside of Firebase Auth and then store image in Storage somehow....")
}
}
private func loginUser() {
FirebaseManager.shared.auth.signIn(withEmail: email, password: password) { result, err in
if let err = err {
print("Failed to login user:", err)
self.loginStatusMessage = "Failed to login user: \(err)"
return
}
print("Successfully logged in as user: \(result?.user.uid ?? "")")
self.loginStatusMessage = "Successfully logged in as user: \(result?.user.uid ?? "")"
self.didCompleteLoginProecess()
}
}
@State var loginStatusMessage = ""
private func createNewAccount() {
if self.image == nil{
self.loginStatusMessage = "你必须选择一张图片"
return
}
FirebaseManager.shared.auth.createUser(withEmail: email, password: password) { result, err in
if let err = err {
print("Failed to create user:", err)
self.loginStatusMessage = "Failed to create user: \(err)"
return
}
print("Successfully created user: \(result?.user.uid ?? "")")
self.loginStatusMessage = "Successfully created user: \(result?.user.uid ?? "")"
self.persistImageToStorage()
}
}
private func persistImageToStorage() {
// let filename = UUID().uuidString
guard let uid = FirebaseManager.shared.auth.currentUser?.uid else { return }
let ref = FirebaseManager.shared.storage.reference(withPath: uid)
guard let imageData = self.image?.jpegData(compressionQuality: 0.5) else { return }
ref.putData(imageData, metadata: nil) { metadata, err in
if let err = err {
self.loginStatusMessage = "Failed to push image to Storage: \(err)"
return
}
ref.downloadURL { url, err in
if let err = err {
self.loginStatusMessage = "Failed to retrieve downloadURL: \(err)"
return
}
self.loginStatusMessage = "Successfully stored image with url: \(url?.absoluteString ?? "")"
print(url!.absoluteString)
guard let url = url else {return}
self.storeUserInformation(imageUrl: url)
}
}
}
private func storeUserInformation(imageUrl: URL){
guard let uid = FirebaseManager.shared.auth.currentUser?.uid else{
return
}
let userData = ["email": self.email,"uid":uid,"profileImageUrl":imageUrl.absoluteString]
FirebaseManager.shared.firestore.collection("users")
.document(uid)
.setData(userData) { err in
if let err = err {
print(err)
self.loginStatusMessage = "\(err)"
return
}
print("Successful")
self.didCompleteLoginProecess()
}
}
}
struct ContentView_Previews1: PreviewProvider {
static var previews: some View {
LoginView(didCompleteLoginProecess: ({
}))
}
}
MainView:
//
// MainMessageView.swift
// LuJunChatDemo
//
// Created by lujun on 2022/4/20.
//
import SwiftUI
import SDWebImageSwiftUI
class MainMessageViewModel: ObservableObject{
@Published var errorMessage = ""
@Published var chatUser: ChatUser?
init(){
DispatchQueue.main.async {
self.isUserCurrentlyLoggedOut = FirebaseManager.shared.auth.currentUser?.uid == nil
}
fetchCurrentUser()
}
func fetchCurrentUser(){
guard let uid = FirebaseManager.shared.auth.currentUser?.uid else{
self.errorMessage = "不能找到firebase uid "
return
}
self.errorMessage = "\(uid)"
FirebaseManager.shared.firestore.collection("users")
.document(uid)
.getDocument { snapshot, error in
if let error = error {
self.errorMessage = error.localizedDescription
print("\(error.localizedDescription)")
return
}
guard let data = snapshot?.data() else {return}
self.chatUser = .init(data: data)
}
}
@Published var isUserCurrentlyLoggedOut = false
func handleSignOut(){
isUserCurrentlyLoggedOut.toggle()
try? FirebaseManager.shared.auth.signOut()
}
}
struct MainMessageView: View {
@State var shouldShowLogOutOptions = false
@ObservedObject var vm = MainMessageViewModel()
var body: some View {
NavigationView{
VStack {
// Text("current user id: \(vm.errorMessage)")
customNavBar
messagesView
.overlay(newMessageButton,alignment: .bottom)
}
.navigationBarHidden(true)
.navigationTitle("消息")
}
}
private var customNavBar: some View {
HStack{
WebImage(url: URL(string: vm.chatUser?.profileImageUrl ?? ""))
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: 50, height: 50)
.clipped()
.cornerRadius(50)
.overlay(Circle().stroke(Color.black,lineWidth: 1))
.shadow(radius: 10)
//Image(systemName: "person.fill")
// .font(.system(size: 34,weight: .heavy))
VStack(alignment: .leading,spacing: 4){
let email = (vm.chatUser?.email ?? "").split(separator: "@").first
Text(email ?? "")
.font(.system(size: 24,weight: .bold))
HStack{
Circle()
.foregroundColor(.green)
.frame(width: 14, height: 14)
Text("在线")
.font(.system(size: 12))
.foregroundColor(Color(.lightGray))
}
}
Spacer()
Button {
shouldShowLogOutOptions.toggle()
} label: {
Image(systemName: "gear")
.font(.system(size: 24, weight: .bold))
}
}
.padding()
.confirmationDialog(
"注销警告?",
isPresented: $shouldShowLogOutOptions,
titleVisibility: .visible) {
Button("注销", role: .destructive) {
// Handle empty trash action.
vm.handleSignOut()
}
} message: {
Text("你想做什么?")
}
.fullScreenCover(isPresented: $vm.isUserCurrentlyLoggedOut) {
// Text("Cover")
LoginView {
self.vm.isUserCurrentlyLoggedOut = false
self.vm.fetchCurrentUser()
}
}
}
}
struct MainMessageView_Previews: PreviewProvider {
static var previews: some View {
MainMessageView()
}
}
extension MainMessageView {
private var messagesView: some View {
ScrollView{
ForEach(0...12,id:\.self){ item in
VStack{
HStack{
Image(systemName: "person.fill")
.font(.system(size: 32))
.padding(8)
.overlay(
RoundedRectangle(cornerRadius: 44)
.stroke(Color.black,lineWidth: 1)
)
VStack(alignment: .leading){
Text("用户名")
.font(.system(size: 16,weight: .bold))
Text("发消息给xxx")
.font(.system(size: 14))
.foregroundColor(Color(.lightGray))
}
Spacer()
Text("xxx")
.font(.system(size: 14,weight: .semibold))
}
Divider()
.padding(.vertical,8)
}
.padding(.horizontal)
}
.padding(.bottom,50)
}
}
private var newMessageButton: some View {
Button {
} label: {
HStack{
Spacer()
Text("+ 新消息")
.font(.system(size: 16,weight: .bold))
Spacer()
}
.foregroundColor(.white)
.padding(.vertical)
.background(Color.blue)
.cornerRadius(32)
.padding(.horizontal)
.shadow(radius: 15)
}
}
}
chatUser
//
// ChatUser.swift
// LuJunChatDemo
//
// Created by lujun on 2022/4/22.
//
import SwiftUI
struct ChatUser{
let uid,email,profileImageUrl: String
init(data: [String: Any]) {
self.uid = data["uid"] as? String ?? ""
self.email = data["email"] as? String ?? ""
self.profileImageUrl = data["profileImageUrl"] as? String ?? ""
}
}