TableView สาธารณะสำหรับผู้ใช้ทั้งหมด

ฉันกำลังสร้างแอปห้องสนทนา ในปัจจุบัน เมื่อผู้ใช้ลงชื่อเข้าใช้ พวกเขาจะได้รับมุมมองตารางของตนเองในการอัปโหลดข้อมูลด้วย

แทนที่จะให้ผู้ใช้แต่ละคนมีมุมมองตารางส่วนตัวเป็นของตัวเอง ฉันต้องการให้ผู้ใช้ทุกคนเชื่อมต่อกับมุมมองตารางเดียว (สาธารณะ) เพื่อให้ทุกคนสามารถเห็นสิ่งที่โพสต์ได้ ดังนั้นแอปห้องสนทนา

  • นี่คือการเข้าสู่ระบบ 3 แบบแยกกัน และลักษณะที่ปรากฏสำหรับผู้ใช้แต่ละคนเมื่อโพสต์ข้อความ:

3 แยกผู้ใช้เมื่อเข้าสู่ระบบและโพสต์ไปที่ Tableview

  • นี่คือสิ่งที่ฉันต้องการ หากต้องการให้แต่ละเซลล์ tableview แสดงข้อความที่แตกต่างจากผู้ใช้รายอื่น ทั้งหมดดูแบบสาธารณะในหนึ่ง tableview ไม่ได้อยู่ในมุมมองตารางแยก:

สิ่งที่ฉันต้องการให้ tableView ทำเมื่อผู้ใช้โพสต์

ฉันจะทำให้มุมมองตารางเป็นแบบสาธารณะได้อย่างไร เมื่อฉันเข้าสู่ระบบในฐานะผู้ใช้อื่น ฉันต้องการให้ข้อความก่อนหน้านี้ยังคงอยู่จากผู้ใช้แต่ละคน จึงมีห้องสนทนา

ป้อนคำอธิบายรูปภาพที่นี่

{
   "rules": {
  "Users":{
     ".read": "true",
     ".write": "true"
},
  "general_room" : {
    ".read": "true",
     ".write": "true"
  }
    }
}

GeneralChatroom.swift

import UIKit
import Foundation
import Firebase
import FirebaseDatabase
import FirebaseStorage

struct postStruct {
    let username : String!
    let message : String!
    let photoURL : String!
}

class GeneralChatroom: UIViewController, UITableViewDataSource, UITableViewDelegate, UITextFieldDelegate {

    @IBOutlet weak var messageTextField: UITextField!

    var generalRoomDataArr = [postStruct]()

    @IBOutlet weak var tableView: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()

        tableView.rowHeight = UITableViewAutomaticDimension
        tableView.estimatedRowHeight = 140


        let ref = FIRDatabase.database().reference()
        let userID = FIRAuth.auth()?.currentUser?.uid            
        ref.child("general_room").child("chat").child(userID!).queryOrderedByKey().observe(.childAdded, with: {snapshot in

            let snapDict = snapshot.value as? NSDictionary
            let username = snapDict?["Username"] as? String ?? ""
            let message = snapDict?["Message"] as? String ?? ""
            let firebaseUserPhotoURL = snapDict?["photo_url"] as? String ?? ""

            self.generalRoomDataArr.insert(postStruct(username: username, message: message, photoURL: firebaseUserPhotoURL), at: 0)
            self.tableView.reloadData()

        })

    }

    @IBAction func backButtonPressed(_ sender: UIButton) {
        self.performSegue(withIdentifier: "BackToRoom", sender: nil)
    }    

    //Message Send button is pressed data uploaded to firebase
    @IBAction func sendButtonPressed(_ sender: UIButton) {

        let message : String = self.messageTextField.text!

        UploadGeneralChatRoom(message: message) //upload to general_room

        self.messageTextField.text = nil
        messageTextField.resignFirstResponder()//Quit keyboard
        self.tableView.reloadData() //Reload tableView
        //UploadUserData() //Update Rank in database
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return generalRoomDataArr.count // your number of cell here
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCell(withIdentifier: "cell")

        let usernameLabel = cell?.viewWithTag(1) as! UILabel
        usernameLabel.text = generalRoomDataArr[indexPath.row].username

        let messageLabel = cell?.viewWithTag(2) as! UILabel
        messageLabel.numberOfLines=0 // line wrap
        messageLabel.lineBreakMode = NSLineBreakMode.byWordWrapping
        messageLabel.text = generalRoomDataArr[indexPath.row].message


        //initialize UI Profile Image
        let imageView = cell?.viewWithTag(3) as! UIImageView

        //Make Porfile Image Cirlce
        imageView.layer.cornerRadius = imageView.frame.size.width/2
        imageView.clipsToBounds = true

        //User Profile image in tableview
        if generalRoomDataArr[indexPath.row].photoURL != nil
        {
            //let imageView = cell?.viewWithTag(3) as! UIImageView

            if let url = NSURL(string: generalRoomDataArr[indexPath.row].photoURL) {

                if let data = NSData(contentsOf: url as URL) {

                    imageView.image = UIImage(data: data as Data)
                }
            }
        }

        // your cell coding
        return cell!
    }       

}//END CLASS

อัปโหลดไปยัง firebase

import Foundation
import Firebase
import FirebaseDatabase
import FirebaseStorage

func UploadGeneralChatRoom(message : String) {

    //Firebase Initialization
    var ref: FIRDatabaseReference!
    //var storage: FIRStorageReference!
    let userID = FIRAuth.auth()?.currentUser?.uid
    ref = FIRDatabase.database().reference()
    //storage = FIRStorage.storage().reference()


    //Get Data from database resend to database
    ref.child("Users").child(userID!).observeSingleEvent(of: .value, with: {(snapshot) in

        let snapDict = snapshot.value as? NSDictionary
        let username = snapDict?["Username"] as? String ?? ""
        let firebaseUserPhotoURL = snapDict?["photo_url"] as? String ?? ""           
        ref.child("general_room").child("chat").child(userID!).childByAutoId().setValue(["Username": username, "uid": userID!, "Message" : message, "photo_url" : firebaseUserPhotoURL])

    })        
}

person nil    schedule 03.03.2017    source แหล่งที่มา
comment
แสดงโครงสร้าง firebase ของคุณให้เราดู   -  person rv7284    schedule 03.03.2017
comment
ในกรณีที่คุณจัดเก็บห้องสนทนาไว้ในผู้ใช้ลูกโดยเฉพาะ คุณต้องสร้างรายการย่อยสาธารณะและจัดเก็บห้องสนทนาทั้งหมดไว้ที่นั่น วิธีนี้ทำให้ผู้ใช้ทุกคนสามารถเข้าถึงห้องสนทนาเหล่านั้นได้   -  person rv7284    schedule 03.03.2017
comment
คุณอาจทำให้งานนี้ซับซ้อนเกินไป: คุณต้องมีโหนดชื่อ General_chat และเมื่อผู้ใช้โพสต์ข้อความไปที่ General_chat โหนดนั้นจะถูกจัดเก็บไว้ในโหนดนั้นตั้งแต่ยังเป็นเด็ก ผู้ใช้ทั้งหมดสังเกตโหนด General_chat และได้รับแจ้งเมื่อมีการเพิ่มข้อความใหม่ ในทางกลับกันเมื่อไคลเอนต์แต่ละรายได้รับเหตุการณ์การแจ้งเตือนนั้น ข้อความจะถูกเพิ่มไปยัง tableView ของไคลเอนต์นั้น ซึ่งจะทำให้ไคลเอ็นต์ทั้งหมดซิงค์กัน เพื่อให้ทุกคนเห็นข้อความใหม่ที่โพสต์ เมื่อใดก็ตามที่ผู้ใช้ใหม่เข้าสู่ระบบ พวกเขาจะสังเกตโหนด General_chat และดูโพสต์ก่อนหน้าทั้งหมด   -  person Jay    schedule 03.03.2017
comment
อาจซ้ำกับ Simulator และอุปกรณ์ iOS tableView Firebase   -  person Jay    schedule 03.03.2017


คำตอบ (1)


ฉันไม่รู้ว่าฐานข้อมูล firebase ของคุณตั้งค่าอย่างไร แต่คุณกำลังโพสต์ไปที่ child("Users").child(userID!) แต่อ่านจาก child("general_room").child("chat").child(userID!)

คุณจะต้องอ่านและเขียนในตำแหน่งเดียวกัน

นอกจากนี้: พยายามแกะค่าทางเลือกของคุณอย่างปลอดภัย:

if let userId = userID {
    ref.child("Users").child(userId).observeSingleEvent(of: .value, with: {(snapshot) in

            let snapDict = snapshot.value as? NSDictionary
            let username = snapDict?["Username"] as? String ?? ""
            let firebaseUserPhotoURL = snapDict?["photo_url"] as? String ?? ""

            ref.child("general_room").child("chat").child(userID!).childByAutoId().setValue(["Username": username, "uid": userID!, "Message" : message, "photo_url" : firebaseUserPhotoURL])
     })
}
person Bob De Kort    schedule 03.03.2017
comment
ที่ที่คุณได้รับข้อมูลของคุณใน viewcontroller คุณเพิ่ม .child(UserID!) หลัง .child(chat) ดังนั้นเมื่อดึงข้อความเหล่านี้ คุณจะต้องมี ID จากผู้ใช้ทุกคนในการแชท หรือตั้งค่าการแชทด้วย ID เพื่อให้ผู้ใช้ทุกคนสามารถเข้าถึงห้องสนทนานั้นได้ - person Bob De Kort; 03.03.2017
comment
Bob De Kort และ @jay ฉันเข้าใจสิ่งที่คุณพูด แต่คุณช่วยอธิบายรายละเอียดเพิ่มเติมได้ไหม หรือแสดงวิธีตั้งค่าให้ฉันดูเพื่อให้ฉันเข้าใจได้ดีขึ้น - person nil; 05.03.2017
comment
@ rv7284 คุณช่วยอธิบายรายละเอียดเพิ่มเติมได้ไหม - person nil; 05.03.2017
comment
ตกลง: ดังนั้นภายใต้ส่วนการแชทของคุณในฐานข้อมูล firebase คุณจะมีกลุ่มข้อความภายใต้รหัส (เช่น: hvl6stvu...) เหล่านี้คือ (เท่าที่ฉันรู้) รหัสผู้ใช้ของคุณ คุณโพสต์ที่นี่โดยใช้รหัสผู้ใช้ของคุณที่เข้าสู่ระบบ ดังนั้นเมื่อดึงข้อมูลด้วยรหัสผู้ใช้ที่เข้าสู่ระบบ คุณจะเข้าถึงได้เฉพาะข้อความผู้ใช้นั้นเท่านั้น - person Bob De Kort; 06.03.2017
comment
แทนสิ่งนี้: ref.child("general_room").child("chat").child(userID!).childByAutoId().setValue(["Username": username, "uid": userID!, "Message" : message, "photo_url" : firebaseUserPhotoURL]) ลบ .child(UserID!) ref.child("general_room").child("chat").childByAutoId().setValue(["Username": username, "uid": userID!, "Message" : message, "photo_url" : firebaseUserPhotoURL]) - person Bob De Kort; 06.03.2017