Firebase Chat - Notification to Other User - swift

I am currently building an app using Firebase, and decided to implement a chat as well.
I was able to use JSQMessagesVC as a GUI, and get the Firebase chat aspect working as well (by combining 2 UID's to create a chatroom, ex: /123_456). However, I am lost on how to notify the other user if they have received a message. (If user 123 opens chatroom 123_456 and sends a message in it, how do I notify user 456 that they have received a message?)
Thanks for the help!

Your question is more related to designing your database. In case implementing chat functionalities you need to rethink about your database structure again. Its all about database structure as Firebase doesn't provide you any trigger so that you can do some actions on other nodes (i.e. database tables) with your primary action in the node you're in.
Though you might've read all those tutorials already, you can take a look again anyway about structuring your data
Here's a nice chat example which might help you in your case. Though its referring to a group chat. You might take a look at how the database is structured for this purpose.
Basically, you need to put some extra actions from client side in different nodes when someone opens a room to chat with others.
Oh here's another SO Answer you should take a look at.

I had the same issue, which I solved by putting in an additional node where each user has a number of chatrooms. put an observer on the user in the chatroom (in below case "0888a5dc-fe8d-4498-aa69-f9dd1361fe54"), with a counter, a description and a timestamp. each new message, update counter, and lastMessage, etc. see below:
"Messages" : {
"0888a5dc-fe8d-4498-aa69-f9dd1361fe54" : {
"0888a5dc-fe8d-4498-aa69-f9dd1361fe5451879163-8b35-452b-9872-a8cb4c84a6ce" : {
"counter" : 2,
"description" : "Breta",
"lastMessage" : “cool”,
"lastUser" : "51879163-8b35-452b-9872-a8cb4c84a6ce",
"messageType" : "txt",
"sortTimestamp" : -1.459518501758476E9,
"updatedAction" : 1.459518501758468E9,
"userId" : "51879163-8b35-452b-9872-a8cb4c84a6ce"
},
"0888a5dc-fe8d-4498-aa69-f9dd1361fe547bfe8604-58ad-4d18-a528-601b76dd2206" : {
"counter" : 0,
"description" : "Romeo",
"lastMessage" : “yep”,
"lastUser" : "0888a5dc-fe8d-4498-aa69-f9dd1361fe54",
"messageType" : "txt",
"sortTimestamp" : -1.459527387138615E9,
"updatedAction" : 1.459527387138613E9,
"userId" : "7bfe8604-58ad-4d18-a528-601b76dd2206"
}
}

Related

Its possible add User Roles on Wordpress by API REST?

Im adding users with JSON but i need to create user roles too for this specific users by API REST, this is poossible ?
So much thanks.
It is possible, by performing a GET request to “wp-json/wp/v2/users”
You can define it using the below example:
{
"username" : "rockstar",
"first_name" : "Seace",
"last_name" : "Kaka",
"email" : "myuser#example.com",
"password" : "Password123!",
"roles" : ["your_role"]
}
To verify the obvious details, just review the documentation:
https://developer.wordpress.org/rest-api/reference/users/#create-a-user

When creating a REST resource, must the representation of that resource be used?

As an example imagine a dynamic pricing system which you can ask for offers moving boxes from 1 place to another. Since the price does not exist before you ask for it it's not as simple as retrieving data from some data-base, but an actual search process needs to run.
What I often see in such scenario's is a request/response based endpoint:
POST /api/offers
{
"customerId" : "123",
"origin" : {"city" : "Amsterdam"},
"destination" : {"city" : "New York"},
"boxes": [{"weight" : 100},{"weight": "200"}]
}
201:
{
"id" : "offerId_123"
"product" : {
"id" : "product_abc",
"name": "box-moving"
}
"totalPrice" : 123.43
}
The request has nothing to do with the response except that one is required to find all information for the other.
The way I interpret "manipulation of resources through representations" I think that this also goes for creation. Following that I would say that one should create the process of searching in stead:
POST /api/offer-searches
{
"request" : {
"customerId" : "123",
"origin" : {"city" : "Amsterdam"},
"destination" : {"city" : "New York"},
"boxes": [{"weight" : 100},{"weight": "200"}]
}
}
201:
{
"id" : "offerSearch_123"
"request" : {
"customerId" : "123",
"origin" : {"city" : "Amsterdam"},
"destination" : {"city" : "New York"},
"boxes": [{"weight" : 100},{"weight": "200"}]
}
offers: [
"id" : "offerId_123"
"product" : {
"id" : "product_abc",
"name": "box-moving"
}
"totalPrice" : 123.43
]
}
Here the request and the response are the same object, during the process it's enhanced with results, but both are still a representation of the same thing, the search process.
This has the advantage of being able to "track" the process, by identifying it it can be read again later. You could still have /api/offers/offerId_123 return the created offer to not have to go through the clutter of the search resource. But it also has quite the trade-off: complexity.
Now my question is, is this first, more RPC like approach something we can even call REST? Or to comply to REST constraints should the 2nd approach be used?
Now my question is, is this first, more RPC like approach something we can even call REST? Or to comply to REST constraints should the 2nd approach be used?
How does the approach compare to how we do things on the web?
For the most part, sending information to a server is realized using HTML forms. So we are dealing with a lot of requests that look something like
POST /efc913bf-ac21-4bf4-8080-467ca8e3e656
Content-Type: application/x-www-form-urlencoded
a=b&c=d
and the responses then look like
201 Created
Location: /a2596478-624f-4775-a490-09edb551a929
Content-Location: /a2596478-624f-4775-a490-09edb551a929
Content-Type: text/html
<html>....</html>
In other words, it's perfectly normal that (a) the representations of the resource are not the information that was sent to the server, but intead something the server computed from the information it was sent and (b) not necessarily of the same schema as the payload of the request... not necessarily even the same media type.
In an anemic document store, you are more likely to be using PUT or PATCH. PATCH requests normally have a patch document in the request-body, so you would expect the representations to be different (think application/json-patch+json). But even in the case of PUT, the server is permitted to make changes to the representation when creating its resource (to make it consistent with its own constraints).
And of course, when you are dealing with responses that contain a representation of "the action", or representations of errors, then once again the response may be quite dissimilar from the request.
TL;DR REST doesn't care if the representation of a bid "matches" the representation of the RFP.
You might decided its a good idea anyway - but it isn't necessary to satisfy REST's constraints, or the semantics of HTTP.

Google Analytics 4 Measurement Protocol shows events but no users

I would like to use Google Analytics from a script (using explicit HTTP requests) and understand that Google Analytics 4 with the Measurement Protocol would be the way to go. I have created a new Property, added a Web tag and created an API key for the Measurement Protocol there. Then I send this request:
{
"client_id": "Test-User",
"user_id": "test_user_id",
"events": [
{
"name": "MyEvent",
"params": {}
}
]
}
To this URL: https://www.google-analytics.com/mp/collect?measurement_id=G-LQDLGRLGZS&api_secret=JXGZ_CyvTt29ucNi9y0DkA
The measurement gets logged there in a corner of the report:
These events don't show up as users. And in reports I don't quite see how to analyze these events. Is there some way to track user sessions by sending special events?
I had the same problem and the answer is here
GA4 Measurement Protocol returns events not the users
Under the events branch of the JSON, when I added
"engagement_time_msec" : 1
the users started to be counted.
"events" : [{
"name" : "SoftMeter_event",
"params" : {
"action" : "From UA-xxxxx [muted]",
"engagement_time_msec" : 1,
"label" : "SoftMeter-dev/v1.0.2/lib v1.4.4 DEBUG"
}
}],
The Measurement Protocol V4 is for GA4 properties(which is also the
one you are using).
According to the official document:
https://support.google.com/analytics/answer/9408920 It says "Google
Analytics 4 properties counts users who engaged with your app/site for
any non-zero amount of time during the previous 30 minutes".
GA4 uses "engagement_time_msec" parameter to identify user interaction
time. This explains why you can see the number of events but not the
number of users. If you want users sent from MP to be counted as
active user, simply add the "engagement_time_msec" parameter to your
event.
client_id is wrong. This id is set by google, so you should get your real id.
You can get it from your cookies for testing. Or, if you use gtag.js you can add this code to your web page.
<script>
gtag('get', <yourMeasurementID>, 'client_id', (clientID) => {
// here you can use clientID
});
</script>

Is it normal to have regular model for GET and "flat" model for POST from Design REST point of view?

The questions about possibility to have different models for POST and GET methods in REST api have been asked several times but I would like to clarify one specific moment.
Suppose we are designing api about sport competition.
Models and corresponding resources:
1) Player
{ "id" : 2,
"firstName" : "Nikolay",
"lastName": "Grigoryan",
.....
}
/players/2
2) Tournament
{ "id" 1,
"name": "Some tournament",
"date" "01.02.2019",
.......
}
/tournaments/1
3) Participant
{
"id": 2,
"tournament": { "id" 1,
"name": "Some tournament",
"date" "01.02.2019",
.......
},
"player": { "id" : 2,
"firstName" : "Nikolay",
"lastName": "Grigoryan",
.....
}
}
/tournament/1/participants/2
When I'm requesting the participants of the certain tournament it's convinient enough to have a separate field by name player containg full nested Player model whith all available fields. But when I'm creating a new participant the situation looks different for me. I would prefer to have just playerId to provide as POST body:
/tournament/1/participants
POST
{
....,
playerId: 2,
.....
}
but not
{
....,
"player": {
"id": 2,
....
}
}
It seems no need to have nested model here but instead only playerId is enough and by this reason no need to have nested object only for holding id at all.
Is it ok to have such simplification of model for POST request or they should be of the same structure? Probably I miss something important by doing such conclusion. If so I would be grateful for explanation what exactly it is.
Thanks in advance.
Is it ok to have such simplification of model for POST request or they should be of the same structure? Probably I miss something important by doing such conclusion. If so I would be grateful for explanation what exactly it is.
How would you do this as a web site?
You'd probably have some sort of form, with a drop down control that lists the identifiers that you might use. The client would choose the identifier from the list, and submit the form. The result would be an HTTP request message with the identifier in the request body.
One approach to at least take inspiration of is to look at HAL.
If a tournament has players, and this is a many-to-many relation it might make sense for players to be associated to a tournament via a link.
To get a list of players, you would simply embed the player resources.
To identify players, you don't use their id, you use their url.
To associate players to a tournament, you could update the links.
As an aside I think that having models that are identical for both receiving (GET) and sending (POST) is a very nice property and makes things easier to understand, but it's also completely fine to abandon this rule where appropriate. I find that especially the situation where people often need a different approach is the case where multiple resources / models are associated with each other. There's not one elegant way to solve this, but using links instead of id's might give you some tools to solve this in a general manner that is applicable everywhere.

REST design for API accessing multiple resources

Imagine an API that returns JSON data for a TV listings app like zap2it TV listings.
It's basically a list of TV channels and for each channel the shows that are on currently and beyond. Currently, I have an API that returns all the channels GET /channels. However, there is a need to add the show currently on for each channel in that data. I am thinking of adding a new API, GET /channels/on_now, to differentiate it from the current API. I want to be clear about this for the new API, I don't want to make individual call for each channel, the show-on-now data needs to be returned for all channels. Is this a good REST API design?
Current GET /channels JSON data
[
"channel": {
"channelName": "KRON4",
},
"channel": {
"channelName": "KTOV5",
},
...
]
Expected JSON data for new API GET /channels/on_now below
[
{
"channel": {
"channelName": "KRON4",
},
"on_now": {
"startTime": "2012-06-04T11:30:00",
"endTime": "2012-06-04T12:00:00",
"shortDescription": "Latest local, statewide & national news events, along with sports & weather.",
"shortTitle": "4:30am Newscast"
}
},
{
"channel": {
"channelName": "KTOV5",
},
"on_now": {
"startTime": "2012-06-04T11:30:00",
"endTime": "2012-06-04T12:30:00",
"shortDescription": "Local morning news and weather report",
"shortTitle": "Morning Newscast"
}
},
...next channel...
]
I would advice to concentrate on content, not on URLs.
Example: you've got an entry point, '/'. This is the only URL in the API. GET on it return st like
{
"channels" : {
"href" : "path.to/channels"
},
"programs" : {
"href" : "path.to/programs"
}
}
To retrieve the list of channels, you GET on the corresponding URL - which you then don't need to know before - and obtain, for example:
[
{
"name" : "BBC",
"id" : 452,
"href" : "path.to/channels/452"
},
{
"name" : "FOO",
"id" : 112,
"href" : "path.to/channels/112"
}
]
For detailled information about BBC, you GET on the provided URL:
{
"name" : "BBC",
"id" : 452,
"self" : "path.to/channels/452",
"live_url" : "link.to.bbc.cast",
"whatever" : "bar",
"current" : "path.to/channels/452/current",
"program" : "path.to/channels/452/program"
}
And so on. URLs are discovered on the fly; you are free to modify them anytime. What makes your API is the content: you have to agree with clients about what is returned (fields, types, ...).
You finally call the "current" URL above to obtain information about current program.
Read here for more: http://kellabyte.com/2011/09/04/clarifying-rest/
Edit after OP-comment:
You could introduce an 'embed' parameter so as to limit amount of requests:
GET path.to/channels/452?embed=current
would return:
{
"name" : "BBC",
"id" : 452,
"self" : "path.to/channels/452",
"live_url" : "link.to.bbc.cast",
"whatever" : "bar",
"current" : {
"self" : "path.to/channels/452/current",
"name" : "Morning Show",
"start_time" : "(datetime here)",
"end_time" : "(datetime here)",
"next" : "whatever.comes.ne/xt"
},
"program" : "path.to/channels/452/program"
}
You asked:
Is this a good REST API design?
YES, it is.
Contrary to the other people who have answered, you are free to define any resource you want to, as long as it represents a noun. That includes time-dependent services such as "what's on TV now" or the perrenial example, "current weather in <city>". These service resources are just as valid as more static ones representing a show or channel.
I would however change the URI. /channels looks like a collection resource URI. I would expect it's children to be channels, such as /channels/kron4 (you can use any unique string, not jsut the ID, to identify instance resources).
As such, /channels/on_now looks odd. It looks like a channel called "on_now". Although there's nothing preventing you from using that, it may later conflict with a channel that is called "On Now"! I would simply use /on_now as your URI. /channels/kron4/on_now would obviously be good for a single channel's response too.
/Channels -----------------------> Get All Channels
/Channels/bbc ------------------> Get BBC Channel
/Channels/bbc/Shows -------------> Get All shows in BBC
/Channels/bbc/Shows/Baseball ----> Get the show called "Baseball", in bbc channel
/Channels/bbc/Shows/current -----> Get the Current show running, in bbc channel
Assuming you do not (and will not ) have a show called Current for any of your channels ! :) .
Just appending to the above answer:
/Channels/bbc/Shows/time/now -----> Get all the show played on BBC now
/Channels/bbc/Shows/time/2011-03-27T03:00:00.000+02:00 -----> Get all the show played on BBC on 2011-03-27T03:00:00.000+02:00 .
This is more extensible and you wont have to worry about any show with the name current.
EDIT:
You can get a good headstart of doing such thing if you can get an api-doc access over here https://developer.sdp.nds.com/page/about
As per me, there would be more data needed and api would be something like:
//epg?time=&start=0&limit=1&duration=
This would define a generic api to get the location based tv_listing information based on time and duration. Result would be paginated with all the show between the channel listing occuring in the given time span.
I'm no API expert, but I think you should be thinking in what you are returning instead of where 'looks like makes sense' to place the resource.
One solution will be to treat on_now as a resource.
so your api will be:
/channels (all channels)
/channels/{channel-id} (the {channel-id} channel - could be bbc and can have a collection of shows)
/channels/{channel-id}/shows (shows of channel-id)
/channels/{channel-id}/shows?filter=on_now (you are filtering a result, so i guess it's better to use query string, as if you were doing a query)
then you want to returns what's on now, that's no a property of the channel but a resource of itself. so how to implement that ?
/on_now/ (return a collection of on_now objects, which may be anything, channels, shows, whatever)
/on_now/?channel={channel-id} (this is a filter of the list by channel-id, you are just narrowing the list)
so isn't /channels/{channel-id}/shows?filter=on_now
the same as /on_now/?channel={channel-id} ?
actually, NO.
In the first uri you are getting shows filtered by a on_now.
In the second you are getting on_nows (which can be any representation, not exclusively a show) filtered by channel.
Why I think on_now should be treated as a resource and why is it important ?
While you make this resource separate, you can now have different representations of your resources. Also you have greater flexibility and no collision. Let's say tomorrow you want to show also in the on_now another 'show' that isn't on any channel, this can easily be done, on the other approachs it just has to be on a channel.
You can also later filter the on_now by different criteria, because they are independent objects.
You can also do:
/on_now/{on_now_id}
that will give details of the current show, like when it started, when it will end and also a place a location to /shows/{show-id} so you can reach it later after it's not on now anymore.
Yet, I think best solution would be to have shows as an unconnected resource to channel.
But the most important thing is, i think you should also need to ask yourself if you want shows to be underlying of channels...
And what hints to think of that is the
I don't want to make individual call for each channel, the
show-on-now data needs to be returned for all channels
part.
That leads me to think that shows should NOT be inside the /channels/ path.
That's because another approach will be to have /shows/?filter=on_now if you are only returning shows.
you can have:
/shows/?filters=on_now&channel=bbc
I like to think of resources as the 'thing' i'm returning instead of the standard thinking of relations alone. Underlying in the graph is great for properties, not so sure about collection of 'other things'.
Following the same example, I would rather have /channels/{channel-id}/program instead of /channels/{channel-id}/shows