Kodeco Forums

Firebase Tutorial: Real-time Chat

Learn how to quickly build a real-time chat-enabled iOS app, written in Swift, that looks and behaves just like Messages with this Firebase tutorial.


This is a companion discussion topic for the original entry at https://www.raywenderlich.com/878-firebase-tutorial-real-time-chat

Great tutorial! I have been working on a Firebase messaging app for the past few weeks and it’s nice to see some signs that I’ve been going about it correctly.
I’m wondering if you have any advice as to how to structure the json models for a one-to-one messaging? I want to try and avoid as much data duplication as possible but at the same time I’m unsure how I can go about filtering conversations that include the current user as a sender OR recipient using the FIRQuery

Especially when a quick check of some sort is needed to see if a conversation with another user already exists or if a new one should be created.
Thoughts? I’m stumped!

{
  "conversations": {
   [
    "ID": "Convo1",
    "messages": {
      "1": { 
        "text": "Hey person!", 
        "senderName": "Alice"
        "senderId": "foo",
        "recipientName": "Bob"
        "recipientId": "bar"
      },
      "2": {
        "text": "Yo!",
        "senderName": "Bob"
        "senderId": "bar",
        "recipientName": "Alice"
        "recipientId": "foo"
      }
    }
  ]
  }

I have also considered the following structure:

{
  "conversations": {
   "Convo1": {
    "messages": {
      "1": { 
        "text": "Hey person!", 
        "senderName": "Alice"
        "senderId": "foo",
        "recipientName": "Bob"
        "recipientId": "bar"
      },
      "2": {
        "text": "Yo!",
        "senderName": "Bob"
        "senderId": "bar",
        "recipientName": "Alice"
        "recipientId": "foo"
      }
    }
  }

Was this even proofread before posting it
 The starter project file podfile is set up for iOS 10. The podfile code snippet we needed to copy does not have an ‘end’ at the end.

The starter project doesn’t run


There is no file ChannelViewController
 Unless you meant ChannelViewListController
 I really wanted to use this tutorial but its abundantly clear that no effort has gone into it.

Starter Project has some issues that are easily converted by Swift auto correct.
The three that are not handled are as follows:
In file UIImage_Gif.swift

    let gifProperties: CFDictionary = unsafeBitCast(
            CFDictionaryGetValue(cfProperties,
                **unsafeAddress(of: kCGImagePropertyGIFDictionary)**),
            to: CFDictionary.self)

The unsafeAddress has been deprecated. Removed in Swift 3. Use Unmanaged.passUnretained(x).toOpaque() instead.

Change the code ro let gifProperties: CFDictionary = unsafeBitCast(
CFDictionaryGetValue(cfProperties,
Unmanaged.passUnretained(kCGImagePropertyGIFDictionary).toOpaque()
),
to: CFDictionary.self)

Full changes should be below:

// Get dictionaries
let cfProperties = CGImageSourceCopyPropertiesAtIndex(source, index, nil)
let gifProperties: CFDictionary = unsafeBitCast(
CFDictionaryGetValue(cfProperties,
Unmanaged.passUnretained(kCGImagePropertyGIFDictionary).toOpaque()
),
to: CFDictionary.self)

    // Get delay time
    var delayObject: AnyObject = unsafeBitCast(
        CFDictionaryGetValue(gifProperties,
        Unmanaged.passUnretained(kCGImagePropertyGIFUnclampedDelayTime).toOpaque()),
        to: AnyObject.self)
    if delayObject.doubleValue == 0 {
        delayObject = unsafeBitCast(CFDictionaryGetValue(gifProperties,
           Unmanaged.passUnretained(kCGImagePropertyGIFDelayTime).toOpaque()), to: AnyObject.self)
                }

Your mileage may vary

2 Likes

@rtemple66 sorry you’re struggling with the tutorial.

To answer your specific questions

  • “The starter project file Podfile is set up for iOS 10.”
    Not sure if this is a question or a reference to the fact that the snippet references iOS 9? This tutorial was written (and proofed) before Xcode 8 was released, but released afterwards. Looks like we missed that.

  • “The podfile code snippet we needed to copy does not have an ‘end’ at the end”
    Generally we only include code that needs adding in snippets. As the end tag is already in the Podfile it probably shouldn’t be in the snippet. The correct thing here is probably to remove everything other than the dependencies from the snippet, which would elevate the first problem you (may have) mentioned.

  • “The starter project doesn’t run
”
    It’s not supposed to. If you follow the tutorial you’ll see that the first part of the tutorial sets up the dependencies and instructs you to setup your Firebase account. Once that’s been done the starter project will run correctly.

  • “There is no file ChannelViewController
 Unless you meant ChannelViewListController”
    Yup, that appears to be a problem. Thanks for flagging.

  • “Also self.addPhotoMessages doesn’t exist in the project
”
    Correct, and I can’t see where that’s referenced anywhere? There is an addPhotoMessage method, and the tutorial shows you where to add that. If I’ve missed something here please do let me know.

As an aside, can I suggest you tone down the attitude a bit. You’ve made a couple of good points in your comments (alongside a couple of duds), but your tone makes it significantly less likely that people will want to engage with you. This can only be a net negative to the community. Thanks :]

Thanks @jamiedaniel, I’ll check that out.

What version of Xcode are you using out of interest?

Hi, Great Tutorial!!
can i install firebase without using cocoapods?
for your opinion, when should i use use firebase over cloudkit?
many thanks,
ohad

@domino1 for me it’s a question of philosophy rather than technology.

CloudKit is designed for really easy, seamless integration with iOS apps. I can’t see Apple pulling the plug on it any time soon and without a really easy upgrade path for developers. And whilst there’s a JS SDK, I don’t feel it’s given as much priority for Apple, and doesn’t integrate well with Android.

Firebase, on the other hand, has supported SDKs for lots of different platforms. But it’s 3rd party to Apple and who knows what Google plan to do with it in the future.

So do you value iOS simplicity & compatibility over multiple OS support?

Personally I’d go for Firebase unless I was 100% confident I was never going to build an Android version of my app.

Hey everyone,
Could you happen to make an android version of this tutorial? I think this would be a great cross platform app, since this is using Firebase. By the way, great tutorial!!!

hello
this is a great tutorial can you advise how to use a blocking mechanism. I really need to add this method its soo important. Thank you

@mmasri you can use User Based Security. In the example in that document they define a rule that a message can be created by a member of the room, like this:

".write": "root.child('members/'+$room_id+'/'+auth.uid).exists()

You could do something similar by having a list of blocked users on your thread/channel and block both read and write access if they current user ID is contained in that list.

@nathanielb I’d probably just use security to prevent other people from joining the thread once it’s created between the two people, and then limit the reads and writes to members of the thread

See Use conditions in Realtime Database Security Rules  |  Firebase Realtime Database.

And as for finding the thread, create an id that’s something really simple like this:

if ($uid_1 < $uid2) {
    $conversation_id = $uid_1 + ':' + $uid_2;
} else {
  $conversation_id = $uid_2 + ':' + $uid_1;
}

Store that on the thread somewhere. Then use a validation rule (Firebase Database Security Rules API) to make sure the thread doesn’t exist when you try and create one.

If the validation fails, you know you can query for it!

I apologize if this has been answered before in the past.

I have always wanted to create a chat application and this seems like it is a great step in the right direction. The one thing you mentioned on where to go from here is having users.

I am more or less just starting out and these tutorials are fantastic but sometimes the core references from the devs are far more than I can understand. Not to say I haven’t tried, but I do struggle excessively with it.

Short and sweet is are there any other resources out there that best described how users can add themselves (signup) and search for other users and have 1 on 1 chats?

Thank you for your time and great tutorials!

How to delete channels and messages? as admin and user

Great tutorial!

the app crashes when i try to add picures.

Really great tutorial!
Since I completed the “Firebase / Get started” tutorial, I was eager to learn more about Firebase.
And especially the instant messaging functionality.

Your tutorial is so much more instructive than Firebase samples. But hey, that’s why Ray wenderlich is the best friend of any iOS dev :wink:

One last thing to do before photos will work on a device: Add an NSCameraUsageDescription to the Info.plist.

https://www.evernote.com/l/AgBnDBJX7pNFu4DXEHiFgNN_b5bJJ8-DAiI

Thanks for the tutorial - a good thorough start. On a real device, I’ve noticed a few things when using the photo attachment capability (after adding the privacy - camera usage item to the info.plist:

  1. on a device you can only take a photo, not choose a photo (like you can on the simulator)
  2. the photo taken when shown in the messages appear squashed and low res
  3. the photos taken do not appear in the camera roll on the device
  4. there is no ability to take a video from the device
  5. there is no way to enlarge the view of photos that appear in the message channel

Many of these may be a matter of further knowledge on my part of JSQMessagesViewController, but any enlightenment or direction would help.

1 Like

Hi!

I am a very novice developper and tried to follow that tutorial from as close as possible.
I have installed pods, configured Firebase but XCode Build fails.

I have deleted the full project and started from scratch 2 times by following the tuto from close but still same result.

Any idea of what I could be missing?
Really looking forward to use that tuto up to the end :]

Thanks!