0

I am building an app and I want the user to be able to tap on a URL using the URL scheme and be sent to a specific view controller on my app. That is working OK. However, I also need to get specific data onto that view controller. I need it so that User A can send an invite (URL) through Messages to User B. User B can tap on that invite (URL) to open a screen with details about the invitation from Firebase. The user can then accept the invite, or decline the invite.

I have setup my database like so:

users(collection)

"uid"(document)

parties(collection)

"partyName"(document)

respondedYes(field)

respondedNo(field)

This is the code that is in the AppDelegate for someone taps on a URL.

func application(_ application: UIApplication, handleOpen url: URL) -> Bool {
    // Open the RSVPViewController.
    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    let rsvpViewController = storyboard.instantiateViewController(withIdentifier: "RSVPViewController") as! RSVPViewController
    
    if let window = self.window, let rootViewController = window.rootViewController {
        var currentController = rootViewController
        while let presentedController = currentController.presentedViewController {
            currentController = presentedController
        }
        currentController.present(rsvpViewController, animated: true, completion: nil)
    }
    return true
}

I don't know how to get it so I know which invitation is being displayed after User B taps the URL so I cannot display the data. How can I get my app to work like I explained in my concept in the first paragraph? Let me know if you need more info. It is really hard to explain what I need help with.

Community
  • 1
  • 1
  • I know there is a well thought out answer but at a high level, you've got the data that both users should see stored in Firestore, right? And that data is stored within a document which has a documentID. A simple solution is to send the other user the documentID of the data you want them to see. When they tap 'See Invite' or whatever interface you are using, get the data from that documentID and display it in the view. – Jay May 26 '19 at 16:31
  • @Jay Thank you for your suggestion. I need to change my database structure around a little bit but that should hopefully work. I really appreciate the other user's answer, however, yes, it is at a high level that is much too complicated for what I am trying to accomplish. –  May 26 '19 at 16:53
  • @Jay How would I send that documentID over to the other user through messages. User A is supposed to be able to send a link to user B via text message. –  May 26 '19 at 19:44
  • There are a number of solutions; have you app observe a node that would notify the app via and event. There are also [Cloud Messaging](https://firebase.google.com/docs/cloud-messaging) as well as [Dynamics Links](https://firebase.google.com/docs/dynamic-links/) and combinations of those. Just depends on the use case. – Jay May 26 '19 at 19:55

1 Answers1

0

In this scenario, the invite URL needs to include parameters that will tell your app which invite User B is opening. This can be achieved with simple GET params in your URL. So for instance your URL now might look like this: myapp:Invite?invite_id=2, where the invite_id param will be dealt with when User B opens the app.

Since it's not the best idea to give other user's access to data under the first user's UID, I would create a new "invitations" collection on firestore, where a new invitation document gets created when user A sends it. The UUID of the newly created invitation document would be the parameter you send in the URL above.

To create this URL, see this answer, Basically you would do the following:

let queryItems = [NSURLQueryItem(name: "invite_id", value: "123")]
let urlComps = NSURLComponents(string: "myapp:Invite")!
urlComps.queryItems = queryItems
let URL = urlComps.URL!

Now, in the application(_:,handleOpen:) (for the receiver's app) you can parse URL params by extending the URL class as explained in this answer.

Assuming you use the extension described in the linked answer(which I tested on playground before recommending here), you can rewrite your function as follows:

func application(_ application: UIApplication, handleOpen url: URL) -> Bool {

    let invite_id = url.valueOf("invite_id")

    // get data from firestore for this invite id and store it in a struct called invite_data 
    // (i'm going to assume that the variable invite_data is defined now).

    // Open the RSVPViewController.
    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    let rsvpViewController = storyboard.instantiateViewController(withIdentifier: "RSVPViewController") as! RSVPViewController

    // tell the rsvpViewController about the data:
    // this assumes you have a variable in rsvpVC that takes this info to display it.
    rsvpViewController.invite_data = invite_data 

    if let window = self.window, let rootViewController = window.rootViewController {
        var currentController = rootViewController
        while let presentedController = currentController.presentedViewController {
            currentController = presentedController
        }
        currentController.present(rsvpViewController, animated: true, completion: nil)
    }
    return true
}

Note that invite_data above is a struct and can contain whatever info you need to both display relevant details in the RSVP VC plus handle things like accepting or declining invites.

An alternate approach would be to simply send all the data you want to display in the rsvpViewController and not bother with an invitation document. Might be easier if the number of fields is small. But I suspect in this scenario you will want to pass things like party_id etc, so depends on your use case.

HirdayGupta
  • 408
  • 4
  • 16
  • I'm still a little bit confused on how to set up the URL with the UUID of the document in the collection "invitations." Are you able to go into that with more detail? –  May 26 '19 at 13:14
  • @MikeD. I update d the answer and added some code explaining how to create the URL. Basically you add the invite_id as a GET param, which the receiver can then use to ask firebase for the invite document in question, to populate the rsvp VC. Let me know if you have more questions. – HirdayGupta May 27 '19 at 22:34