Firestore listener for sub collections









up vote
1
down vote

favorite












I have my Firestore setup in the following way:



Channels [collection] ----> channelID ---> Messages [collection] --->
messageID



How would I add snapshotListener to sub collection 'Messages' ?



 Firestore.firestore().collection("Channels").document().collection("Messages").addSnapshotListener (querySnapshot, error) in
guard let snapshot = querySnapshot else
print("Error listening for channel updates: (error?.localizedDescription ?? "No error")")
return


snapshot.documentChanges.forEach change in
print(change)




This didn't work for me










share|improve this question























  • Why you say it didn't work? Do you have an error?
    – Alex Mamo
    Nov 9 at 14:16










  • When I add a new message, this listener is not called
    – OuSS
    Nov 9 at 14:18










  • In this case, please add more code.
    – Alex Mamo
    Nov 9 at 14:19










  • I updated the post
    – OuSS
    Nov 9 at 14:22














up vote
1
down vote

favorite












I have my Firestore setup in the following way:



Channels [collection] ----> channelID ---> Messages [collection] --->
messageID



How would I add snapshotListener to sub collection 'Messages' ?



 Firestore.firestore().collection("Channels").document().collection("Messages").addSnapshotListener (querySnapshot, error) in
guard let snapshot = querySnapshot else
print("Error listening for channel updates: (error?.localizedDescription ?? "No error")")
return


snapshot.documentChanges.forEach change in
print(change)




This didn't work for me










share|improve this question























  • Why you say it didn't work? Do you have an error?
    – Alex Mamo
    Nov 9 at 14:16










  • When I add a new message, this listener is not called
    – OuSS
    Nov 9 at 14:18










  • In this case, please add more code.
    – Alex Mamo
    Nov 9 at 14:19










  • I updated the post
    – OuSS
    Nov 9 at 14:22












up vote
1
down vote

favorite









up vote
1
down vote

favorite











I have my Firestore setup in the following way:



Channels [collection] ----> channelID ---> Messages [collection] --->
messageID



How would I add snapshotListener to sub collection 'Messages' ?



 Firestore.firestore().collection("Channels").document().collection("Messages").addSnapshotListener (querySnapshot, error) in
guard let snapshot = querySnapshot else
print("Error listening for channel updates: (error?.localizedDescription ?? "No error")")
return


snapshot.documentChanges.forEach change in
print(change)




This didn't work for me










share|improve this question















I have my Firestore setup in the following way:



Channels [collection] ----> channelID ---> Messages [collection] --->
messageID



How would I add snapshotListener to sub collection 'Messages' ?



 Firestore.firestore().collection("Channels").document().collection("Messages").addSnapshotListener (querySnapshot, error) in
guard let snapshot = querySnapshot else
print("Error listening for channel updates: (error?.localizedDescription ?? "No error")")
return


snapshot.documentChanges.forEach change in
print(change)




This didn't work for me







ios swift firebase google-cloud-firestore






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 9 at 14:21

























asked Nov 9 at 14:14









OuSS

202113




202113











  • Why you say it didn't work? Do you have an error?
    – Alex Mamo
    Nov 9 at 14:16










  • When I add a new message, this listener is not called
    – OuSS
    Nov 9 at 14:18










  • In this case, please add more code.
    – Alex Mamo
    Nov 9 at 14:19










  • I updated the post
    – OuSS
    Nov 9 at 14:22
















  • Why you say it didn't work? Do you have an error?
    – Alex Mamo
    Nov 9 at 14:16










  • When I add a new message, this listener is not called
    – OuSS
    Nov 9 at 14:18










  • In this case, please add more code.
    – Alex Mamo
    Nov 9 at 14:19










  • I updated the post
    – OuSS
    Nov 9 at 14:22















Why you say it didn't work? Do you have an error?
– Alex Mamo
Nov 9 at 14:16




Why you say it didn't work? Do you have an error?
– Alex Mamo
Nov 9 at 14:16












When I add a new message, this listener is not called
– OuSS
Nov 9 at 14:18




When I add a new message, this listener is not called
– OuSS
Nov 9 at 14:18












In this case, please add more code.
– Alex Mamo
Nov 9 at 14:19




In this case, please add more code.
– Alex Mamo
Nov 9 at 14:19












I updated the post
– OuSS
Nov 9 at 14:22




I updated the post
– OuSS
Nov 9 at 14:22












3 Answers
3






active

oldest

votes

















up vote
1
down vote













You can't have a single listener receive updates from an unknown number of subcollection. There are no "wildcard" operators for listeners on collections. You have to choose a specific collection or query and attach a listener to that.






share|improve this answer



























    up vote
    0
    down vote













    I think it is because with



    Firestore.firestore().collection("Channels").document().collection("Messages")


    you are not defining a correct CollectionReference since you don't identify the document of the "Channels" collection.



    You should do:



    Firestore.firestore().collection("Channels").document(channelID).collection("Messages")





    share|improve this answer




















    • This is not what i want, with your code i will just listen to one channel that have id == channelID but me i want to listen to all Channels
      – OuSS
      Nov 9 at 14:42











    • Update: see Doug's answer. What you want is not possible. If you listen to Firestore.firestore().collection("Channels") the doc says that "the snapshot handler will receive a new query snapshot every time the query results change (that is, when a document is added, removed, or modified)".
      – Renaud Tarnec
      Nov 9 at 14:47











    • Ok so i think the best solution it to move Messages to be a root collection and inside message add field channelID
      – OuSS
      Nov 9 at 14:48










    • Yes, that would be a solution.
      – Renaud Tarnec
      Nov 9 at 14:54

















    up vote
    0
    down vote













    As Doug pointed out in his correct answer, you cannot have a single listener receive updates from an unknown (number of or unspecified) subcollection.



    However, if you can determine those subcollection names, then the answer is pretty straightforward.



    The idea is to read the child nodes of Channels, which will be channel_0, channel_1 etc and use those document id's to build references to the nodes you are interested in listening to.



    So given this struture (which matches the structure in the question):



    Channels
    channel_0
    Messages
    message_0
    msg: "chan 0 msg 0"
    message_1
    msg: "chan 0 msg 1"
    message_2
    msg: "chan 0 msg 2"
    channel_1
    Messages
    message_0
    msg: "chan 1 msg 0"
    message_1
    msg: "chan 1 msg 1"


    Here's the code that adds listeners to each channel, and responds to events within that channels messages notifying in console the message id, msg text and the channel the event occurred in.



    func addChannelCollectionObserver() 
    let channelsRef = self.db.collection("Channels")
    channelsRef.getDocuments(completion: snapshot, error in

    guard let documents = snapshot?.documents else
    print("Collection was empty")
    return


    for doc in documents
    let docID = doc.documentID
    let eachChannelRef = channelsRef.document(docID)
    let messagesRef = eachChannelRef.collection("Messages")

    messagesRef.addSnapshotListener querySnapshot, error in

    querySnapshot?.documentChanges.forEach diff in
    if diff.type == .added
    let doc = diff.document
    let msgId = doc.documentID
    let channelId = messagesRef.parent!.documentID
    let msg = doc.get("msg") as? String ?? "no message"
    print(" added msgId: (msgId) with msg: (msg) in channel: (channelId)")


    if diff.type == .modified
    let doc = diff.document
    let msgId = doc.documentID
    let msg = doc.get("msg") as? String ?? "no message"
    print(" modified msgId: (msgId) with msg: (msg)")


    if diff.type == .removed
    let doc = diff.document
    let msgId = doc.documentID
    let msg = doc.get("msg") as? String ?? "no message"
    print(" removed msgId: (msgId) with msg: (msg)")




    )



    When first run the output will show, as expected, each child node. From then on it will output any addititions, modifications or deletions.



     added msgId: message_0 with msg: chan 0 msg 0 in channel: channel_0
    added msgId: message_1 with msg: chan 0 msg 1 in channel: channel_0
    added msgId: message_2 with msg: chan 0 msg 2 in channel: channel_0
    added msgId: message_0 with msg: chan 1 msg 0 in channel: channel_1
    added msgId: message_1 with msg: chan 1 msg 1 in channel: channel_1


    the code needs some additional error checking as well for some of the optionals but it should provide a solution.






    share|improve this answer




















      Your Answer






      StackExchange.ifUsing("editor", function ()
      StackExchange.using("externalEditor", function ()
      StackExchange.using("snippets", function ()
      StackExchange.snippets.init();
      );
      );
      , "code-snippets");

      StackExchange.ready(function()
      var channelOptions =
      tags: "".split(" "),
      id: "1"
      ;
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function()
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled)
      StackExchange.using("snippets", function()
      createEditor();
      );

      else
      createEditor();

      );

      function createEditor()
      StackExchange.prepareEditor(
      heartbeatType: 'answer',
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader:
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      ,
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      );



      );













       

      draft saved


      draft discarded


















      StackExchange.ready(
      function ()
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53227376%2ffirestore-listener-for-sub-collections%23new-answer', 'question_page');

      );

      Post as a guest















      Required, but never shown

























      3 Answers
      3






      active

      oldest

      votes








      3 Answers
      3






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes








      up vote
      1
      down vote













      You can't have a single listener receive updates from an unknown number of subcollection. There are no "wildcard" operators for listeners on collections. You have to choose a specific collection or query and attach a listener to that.






      share|improve this answer
























        up vote
        1
        down vote













        You can't have a single listener receive updates from an unknown number of subcollection. There are no "wildcard" operators for listeners on collections. You have to choose a specific collection or query and attach a listener to that.






        share|improve this answer






















          up vote
          1
          down vote










          up vote
          1
          down vote









          You can't have a single listener receive updates from an unknown number of subcollection. There are no "wildcard" operators for listeners on collections. You have to choose a specific collection or query and attach a listener to that.






          share|improve this answer












          You can't have a single listener receive updates from an unknown number of subcollection. There are no "wildcard" operators for listeners on collections. You have to choose a specific collection or query and attach a listener to that.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 9 at 14:48









          Doug Stevenson

          65.9k77997




          65.9k77997






















              up vote
              0
              down vote













              I think it is because with



              Firestore.firestore().collection("Channels").document().collection("Messages")


              you are not defining a correct CollectionReference since you don't identify the document of the "Channels" collection.



              You should do:



              Firestore.firestore().collection("Channels").document(channelID).collection("Messages")





              share|improve this answer




















              • This is not what i want, with your code i will just listen to one channel that have id == channelID but me i want to listen to all Channels
                – OuSS
                Nov 9 at 14:42











              • Update: see Doug's answer. What you want is not possible. If you listen to Firestore.firestore().collection("Channels") the doc says that "the snapshot handler will receive a new query snapshot every time the query results change (that is, when a document is added, removed, or modified)".
                – Renaud Tarnec
                Nov 9 at 14:47











              • Ok so i think the best solution it to move Messages to be a root collection and inside message add field channelID
                – OuSS
                Nov 9 at 14:48










              • Yes, that would be a solution.
                – Renaud Tarnec
                Nov 9 at 14:54














              up vote
              0
              down vote













              I think it is because with



              Firestore.firestore().collection("Channels").document().collection("Messages")


              you are not defining a correct CollectionReference since you don't identify the document of the "Channels" collection.



              You should do:



              Firestore.firestore().collection("Channels").document(channelID).collection("Messages")





              share|improve this answer




















              • This is not what i want, with your code i will just listen to one channel that have id == channelID but me i want to listen to all Channels
                – OuSS
                Nov 9 at 14:42











              • Update: see Doug's answer. What you want is not possible. If you listen to Firestore.firestore().collection("Channels") the doc says that "the snapshot handler will receive a new query snapshot every time the query results change (that is, when a document is added, removed, or modified)".
                – Renaud Tarnec
                Nov 9 at 14:47











              • Ok so i think the best solution it to move Messages to be a root collection and inside message add field channelID
                – OuSS
                Nov 9 at 14:48










              • Yes, that would be a solution.
                – Renaud Tarnec
                Nov 9 at 14:54












              up vote
              0
              down vote










              up vote
              0
              down vote









              I think it is because with



              Firestore.firestore().collection("Channels").document().collection("Messages")


              you are not defining a correct CollectionReference since you don't identify the document of the "Channels" collection.



              You should do:



              Firestore.firestore().collection("Channels").document(channelID).collection("Messages")





              share|improve this answer












              I think it is because with



              Firestore.firestore().collection("Channels").document().collection("Messages")


              you are not defining a correct CollectionReference since you don't identify the document of the "Channels" collection.



              You should do:



              Firestore.firestore().collection("Channels").document(channelID).collection("Messages")






              share|improve this answer












              share|improve this answer



              share|improve this answer










              answered Nov 9 at 14:39









              Renaud Tarnec

              9,28621431




              9,28621431











              • This is not what i want, with your code i will just listen to one channel that have id == channelID but me i want to listen to all Channels
                – OuSS
                Nov 9 at 14:42











              • Update: see Doug's answer. What you want is not possible. If you listen to Firestore.firestore().collection("Channels") the doc says that "the snapshot handler will receive a new query snapshot every time the query results change (that is, when a document is added, removed, or modified)".
                – Renaud Tarnec
                Nov 9 at 14:47











              • Ok so i think the best solution it to move Messages to be a root collection and inside message add field channelID
                – OuSS
                Nov 9 at 14:48










              • Yes, that would be a solution.
                – Renaud Tarnec
                Nov 9 at 14:54
















              • This is not what i want, with your code i will just listen to one channel that have id == channelID but me i want to listen to all Channels
                – OuSS
                Nov 9 at 14:42











              • Update: see Doug's answer. What you want is not possible. If you listen to Firestore.firestore().collection("Channels") the doc says that "the snapshot handler will receive a new query snapshot every time the query results change (that is, when a document is added, removed, or modified)".
                – Renaud Tarnec
                Nov 9 at 14:47











              • Ok so i think the best solution it to move Messages to be a root collection and inside message add field channelID
                – OuSS
                Nov 9 at 14:48










              • Yes, that would be a solution.
                – Renaud Tarnec
                Nov 9 at 14:54















              This is not what i want, with your code i will just listen to one channel that have id == channelID but me i want to listen to all Channels
              – OuSS
              Nov 9 at 14:42





              This is not what i want, with your code i will just listen to one channel that have id == channelID but me i want to listen to all Channels
              – OuSS
              Nov 9 at 14:42













              Update: see Doug's answer. What you want is not possible. If you listen to Firestore.firestore().collection("Channels") the doc says that "the snapshot handler will receive a new query snapshot every time the query results change (that is, when a document is added, removed, or modified)".
              – Renaud Tarnec
              Nov 9 at 14:47





              Update: see Doug's answer. What you want is not possible. If you listen to Firestore.firestore().collection("Channels") the doc says that "the snapshot handler will receive a new query snapshot every time the query results change (that is, when a document is added, removed, or modified)".
              – Renaud Tarnec
              Nov 9 at 14:47













              Ok so i think the best solution it to move Messages to be a root collection and inside message add field channelID
              – OuSS
              Nov 9 at 14:48




              Ok so i think the best solution it to move Messages to be a root collection and inside message add field channelID
              – OuSS
              Nov 9 at 14:48












              Yes, that would be a solution.
              – Renaud Tarnec
              Nov 9 at 14:54




              Yes, that would be a solution.
              – Renaud Tarnec
              Nov 9 at 14:54










              up vote
              0
              down vote













              As Doug pointed out in his correct answer, you cannot have a single listener receive updates from an unknown (number of or unspecified) subcollection.



              However, if you can determine those subcollection names, then the answer is pretty straightforward.



              The idea is to read the child nodes of Channels, which will be channel_0, channel_1 etc and use those document id's to build references to the nodes you are interested in listening to.



              So given this struture (which matches the structure in the question):



              Channels
              channel_0
              Messages
              message_0
              msg: "chan 0 msg 0"
              message_1
              msg: "chan 0 msg 1"
              message_2
              msg: "chan 0 msg 2"
              channel_1
              Messages
              message_0
              msg: "chan 1 msg 0"
              message_1
              msg: "chan 1 msg 1"


              Here's the code that adds listeners to each channel, and responds to events within that channels messages notifying in console the message id, msg text and the channel the event occurred in.



              func addChannelCollectionObserver() 
              let channelsRef = self.db.collection("Channels")
              channelsRef.getDocuments(completion: snapshot, error in

              guard let documents = snapshot?.documents else
              print("Collection was empty")
              return


              for doc in documents
              let docID = doc.documentID
              let eachChannelRef = channelsRef.document(docID)
              let messagesRef = eachChannelRef.collection("Messages")

              messagesRef.addSnapshotListener querySnapshot, error in

              querySnapshot?.documentChanges.forEach diff in
              if diff.type == .added
              let doc = diff.document
              let msgId = doc.documentID
              let channelId = messagesRef.parent!.documentID
              let msg = doc.get("msg") as? String ?? "no message"
              print(" added msgId: (msgId) with msg: (msg) in channel: (channelId)")


              if diff.type == .modified
              let doc = diff.document
              let msgId = doc.documentID
              let msg = doc.get("msg") as? String ?? "no message"
              print(" modified msgId: (msgId) with msg: (msg)")


              if diff.type == .removed
              let doc = diff.document
              let msgId = doc.documentID
              let msg = doc.get("msg") as? String ?? "no message"
              print(" removed msgId: (msgId) with msg: (msg)")




              )



              When first run the output will show, as expected, each child node. From then on it will output any addititions, modifications or deletions.



               added msgId: message_0 with msg: chan 0 msg 0 in channel: channel_0
              added msgId: message_1 with msg: chan 0 msg 1 in channel: channel_0
              added msgId: message_2 with msg: chan 0 msg 2 in channel: channel_0
              added msgId: message_0 with msg: chan 1 msg 0 in channel: channel_1
              added msgId: message_1 with msg: chan 1 msg 1 in channel: channel_1


              the code needs some additional error checking as well for some of the optionals but it should provide a solution.






              share|improve this answer
























                up vote
                0
                down vote













                As Doug pointed out in his correct answer, you cannot have a single listener receive updates from an unknown (number of or unspecified) subcollection.



                However, if you can determine those subcollection names, then the answer is pretty straightforward.



                The idea is to read the child nodes of Channels, which will be channel_0, channel_1 etc and use those document id's to build references to the nodes you are interested in listening to.



                So given this struture (which matches the structure in the question):



                Channels
                channel_0
                Messages
                message_0
                msg: "chan 0 msg 0"
                message_1
                msg: "chan 0 msg 1"
                message_2
                msg: "chan 0 msg 2"
                channel_1
                Messages
                message_0
                msg: "chan 1 msg 0"
                message_1
                msg: "chan 1 msg 1"


                Here's the code that adds listeners to each channel, and responds to events within that channels messages notifying in console the message id, msg text and the channel the event occurred in.



                func addChannelCollectionObserver() 
                let channelsRef = self.db.collection("Channels")
                channelsRef.getDocuments(completion: snapshot, error in

                guard let documents = snapshot?.documents else
                print("Collection was empty")
                return


                for doc in documents
                let docID = doc.documentID
                let eachChannelRef = channelsRef.document(docID)
                let messagesRef = eachChannelRef.collection("Messages")

                messagesRef.addSnapshotListener querySnapshot, error in

                querySnapshot?.documentChanges.forEach diff in
                if diff.type == .added
                let doc = diff.document
                let msgId = doc.documentID
                let channelId = messagesRef.parent!.documentID
                let msg = doc.get("msg") as? String ?? "no message"
                print(" added msgId: (msgId) with msg: (msg) in channel: (channelId)")


                if diff.type == .modified
                let doc = diff.document
                let msgId = doc.documentID
                let msg = doc.get("msg") as? String ?? "no message"
                print(" modified msgId: (msgId) with msg: (msg)")


                if diff.type == .removed
                let doc = diff.document
                let msgId = doc.documentID
                let msg = doc.get("msg") as? String ?? "no message"
                print(" removed msgId: (msgId) with msg: (msg)")




                )



                When first run the output will show, as expected, each child node. From then on it will output any addititions, modifications or deletions.



                 added msgId: message_0 with msg: chan 0 msg 0 in channel: channel_0
                added msgId: message_1 with msg: chan 0 msg 1 in channel: channel_0
                added msgId: message_2 with msg: chan 0 msg 2 in channel: channel_0
                added msgId: message_0 with msg: chan 1 msg 0 in channel: channel_1
                added msgId: message_1 with msg: chan 1 msg 1 in channel: channel_1


                the code needs some additional error checking as well for some of the optionals but it should provide a solution.






                share|improve this answer






















                  up vote
                  0
                  down vote










                  up vote
                  0
                  down vote









                  As Doug pointed out in his correct answer, you cannot have a single listener receive updates from an unknown (number of or unspecified) subcollection.



                  However, if you can determine those subcollection names, then the answer is pretty straightforward.



                  The idea is to read the child nodes of Channels, which will be channel_0, channel_1 etc and use those document id's to build references to the nodes you are interested in listening to.



                  So given this struture (which matches the structure in the question):



                  Channels
                  channel_0
                  Messages
                  message_0
                  msg: "chan 0 msg 0"
                  message_1
                  msg: "chan 0 msg 1"
                  message_2
                  msg: "chan 0 msg 2"
                  channel_1
                  Messages
                  message_0
                  msg: "chan 1 msg 0"
                  message_1
                  msg: "chan 1 msg 1"


                  Here's the code that adds listeners to each channel, and responds to events within that channels messages notifying in console the message id, msg text and the channel the event occurred in.



                  func addChannelCollectionObserver() 
                  let channelsRef = self.db.collection("Channels")
                  channelsRef.getDocuments(completion: snapshot, error in

                  guard let documents = snapshot?.documents else
                  print("Collection was empty")
                  return


                  for doc in documents
                  let docID = doc.documentID
                  let eachChannelRef = channelsRef.document(docID)
                  let messagesRef = eachChannelRef.collection("Messages")

                  messagesRef.addSnapshotListener querySnapshot, error in

                  querySnapshot?.documentChanges.forEach diff in
                  if diff.type == .added
                  let doc = diff.document
                  let msgId = doc.documentID
                  let channelId = messagesRef.parent!.documentID
                  let msg = doc.get("msg") as? String ?? "no message"
                  print(" added msgId: (msgId) with msg: (msg) in channel: (channelId)")


                  if diff.type == .modified
                  let doc = diff.document
                  let msgId = doc.documentID
                  let msg = doc.get("msg") as? String ?? "no message"
                  print(" modified msgId: (msgId) with msg: (msg)")


                  if diff.type == .removed
                  let doc = diff.document
                  let msgId = doc.documentID
                  let msg = doc.get("msg") as? String ?? "no message"
                  print(" removed msgId: (msgId) with msg: (msg)")




                  )



                  When first run the output will show, as expected, each child node. From then on it will output any addititions, modifications or deletions.



                   added msgId: message_0 with msg: chan 0 msg 0 in channel: channel_0
                  added msgId: message_1 with msg: chan 0 msg 1 in channel: channel_0
                  added msgId: message_2 with msg: chan 0 msg 2 in channel: channel_0
                  added msgId: message_0 with msg: chan 1 msg 0 in channel: channel_1
                  added msgId: message_1 with msg: chan 1 msg 1 in channel: channel_1


                  the code needs some additional error checking as well for some of the optionals but it should provide a solution.






                  share|improve this answer












                  As Doug pointed out in his correct answer, you cannot have a single listener receive updates from an unknown (number of or unspecified) subcollection.



                  However, if you can determine those subcollection names, then the answer is pretty straightforward.



                  The idea is to read the child nodes of Channels, which will be channel_0, channel_1 etc and use those document id's to build references to the nodes you are interested in listening to.



                  So given this struture (which matches the structure in the question):



                  Channels
                  channel_0
                  Messages
                  message_0
                  msg: "chan 0 msg 0"
                  message_1
                  msg: "chan 0 msg 1"
                  message_2
                  msg: "chan 0 msg 2"
                  channel_1
                  Messages
                  message_0
                  msg: "chan 1 msg 0"
                  message_1
                  msg: "chan 1 msg 1"


                  Here's the code that adds listeners to each channel, and responds to events within that channels messages notifying in console the message id, msg text and the channel the event occurred in.



                  func addChannelCollectionObserver() 
                  let channelsRef = self.db.collection("Channels")
                  channelsRef.getDocuments(completion: snapshot, error in

                  guard let documents = snapshot?.documents else
                  print("Collection was empty")
                  return


                  for doc in documents
                  let docID = doc.documentID
                  let eachChannelRef = channelsRef.document(docID)
                  let messagesRef = eachChannelRef.collection("Messages")

                  messagesRef.addSnapshotListener querySnapshot, error in

                  querySnapshot?.documentChanges.forEach diff in
                  if diff.type == .added
                  let doc = diff.document
                  let msgId = doc.documentID
                  let channelId = messagesRef.parent!.documentID
                  let msg = doc.get("msg") as? String ?? "no message"
                  print(" added msgId: (msgId) with msg: (msg) in channel: (channelId)")


                  if diff.type == .modified
                  let doc = diff.document
                  let msgId = doc.documentID
                  let msg = doc.get("msg") as? String ?? "no message"
                  print(" modified msgId: (msgId) with msg: (msg)")


                  if diff.type == .removed
                  let doc = diff.document
                  let msgId = doc.documentID
                  let msg = doc.get("msg") as? String ?? "no message"
                  print(" removed msgId: (msgId) with msg: (msg)")




                  )



                  When first run the output will show, as expected, each child node. From then on it will output any addititions, modifications or deletions.



                   added msgId: message_0 with msg: chan 0 msg 0 in channel: channel_0
                  added msgId: message_1 with msg: chan 0 msg 1 in channel: channel_0
                  added msgId: message_2 with msg: chan 0 msg 2 in channel: channel_0
                  added msgId: message_0 with msg: chan 1 msg 0 in channel: channel_1
                  added msgId: message_1 with msg: chan 1 msg 1 in channel: channel_1


                  the code needs some additional error checking as well for some of the optionals but it should provide a solution.







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Nov 11 at 15:39









                  Jay

                  18k42848




                  18k42848



























                       

                      draft saved


                      draft discarded















































                       


                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function ()
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53227376%2ffirestore-listener-for-sub-collections%23new-answer', 'question_page');

                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      Top Tejano songwriter Luis Silva dead of heart attack at 64

                      ReactJS Fetched API data displays live - need Data displayed static

                      Evgeni Malkin