TableView общедоступен для всех пользователей

Я создаю приложение для чата. В настоящее время, когда пользователи входят в систему, им также предоставляется собственное табличное представление для загрузки данных.

Вместо того, чтобы у каждого пользователя было собственное личное табличное представление, я бы хотел, чтобы все пользователи были подключены к одному (общедоступному) табличному представлению, чтобы каждый мог видеть, что опубликовано. Следовательно, приложение чата.

  • Это 3 отдельных логина и то, как это выглядит для каждого пользователя, когда он публикует сообщение:

3 Разделяйте пользователей при входе в систему и публикации в 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
Когда вы получаете свои данные в своем контроллере представления, вы добавляете .child(UserID!) после .child(chat). Поэтому при получении этих сообщений вам необходимо либо получить идентификатор от всех пользователей в чате, либо настроить чат с идентификатором, чтобы все пользователи могли получить доступ к этому чату. - person Bob De Kort; 03.03.2017
comment
Боб Де Корт и @jay, я вроде как понимаю, о чем вы говорите, но не могли бы вы рассказать подробнее. Или покажите мне, как настроить его, чтобы я лучше понял. - person nil; 05.03.2017
comment
@rv7284 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