How does feathers sequelize work - postgresql

I'm using angular2 on frontend, node/feathers on backend over Postgres (sequelize) db.
On backend I have events service on ".../events" route, and I'm trying to reach data from db, it works fine when I want to retrieve all events so I just make request on this route.. or when I want to retrieve just one event with certain id (make request on "../events/>>id<<). But how to get data by other attributes, for example I have user and its in association with event one to many, so how would I retrieve all events for one user (search by user id, not by events id). Or any other attribute, for example by name, return all events with certain name. How would that work, any code example?
In events model I have relation with user as one to many (event has creator) and I made that connection as events.belongsTo(user). How can I add that this same event has also many to many relation with users cause it has also attribute "participants" as users that are also included into this event, and every user can participate or own many events.

Found it myself, just add ?attribute=value... so if i want all events owned by user with id 1... it would be ".../events?userId=1 ... and this would return me all the events with userId=1... same goes with any other attribute –

Related

Firebase functions solution for building a secure Chat App with Seen functionality

I am building a chat app using Flutter and Firebase.
The way it works in Firebase Firestore is really simple, I just have a conversationId which represents the documents where there are the messages, all of the users have a list of their conversations, when they tap on a conversation, a new screen pops up where they see the messages based on data from the stream of the "Messages" collection that is under the conversationId document. Basically that's the structure
col: Chats
doc: conversationId
col: Messages
message documents...
And this is how I get the messages inside the Chat Screen.
_firestore
.collection("Chats")
.doc(_messageCollectionId)
.collection("Messages")
.orderBy("sentOn", descending: true)
.snapshots()
.map(...)
The message document is basically the message text and when it was sent and who sent it.
I want to create the "seen" functionality, inherently I want the user to see what conversation he read or not (which ones have new messages, like instagram chat or discord)
I can not come up with a good solution to this, my main 2 problems are:
If I were to call a cloud function which fetches the messages and somehow marks them as being read, that would break my app, as I need a continous stream of live message data for the chat to feel good, I can not stream data from the cloud function.
I would like to create a system which is not write intensive. If I would have to mark each message document in particular with some "seenOn :timestamp" value, that would mean that if the user is reading 200 new messages, there are 200 new writes on each document, which seems too much to me, there should be another way.
I am asking for guidance on how I should go about the architecture of such a chat using Firebase. Maybe my chat model is not really fit for what I need, how should I tweak it?
Another problem is that I do not know how the "seen" signal should be sent. If I manually write to a document and change the boolean value of some "isRead" field from my client, the client could easily skip that line of code and break my whole seen system, they could read messages without sending the seen signal just with a break point. This is quite exploitable, there is no cloud function trigger on documents "onRead" that could help me move that logic outside the client, so what is the solution to make this also secure?
so if you want to create the seen function you could made the database structure look like this first
you should create 2 collection for the db, the users collection would only save user data and in the chats collection inside of the uid is saving the chat room id that would be look like this
that was the collection inside of users. only put the roomId of connection that been made when user trying to send a new message to other user. put the the field exactly look like that. after that you could create a chatroom collection that look like this
to be sure that random uid inside of chats collection is a room id that you should register in your users/doc/chats/ collection. the field inside of the roomId would be a connection between of the 2 user for accesing the message that've been send to db. and inside of the chat collection you would send message data in this format
and after you put that you could retrieve the chat data using stream function that would look like this
Stream<QuerySnapshot<Map<String, dynamic>>> streamChats(String chatId) {
CollectionReference chats = firestore.collection("chats");
return chats.doc(chatId).collection("chat").orderBy("time").snapshots();
}
each time of user sending message you could put the total of message that've been send to other user in the total_unread field and update it when other of user open the chat roomId. and tada your seen could work properly
oh and you can create a function that check the total_unread is 0 already and you can put the seen/check icon beside of your user message bubble.

Best frontend practice for saving object to a backend before or after creation

situation: Lets's think about basic process of object creation on a client (with CRUD backend).
Let's imagine that we have two "Create" buttons on a page.
first case:
Clicking on the first button will cause to redirect to /create route, where our form located.
After we fill the form with data, we post it to a backend and it retrieves an id of a newly created object.
second case:
Clicking on the second button will cause to send creation request to the backend, then after we got a new object id, we will be redirected to /edit/:id, where our form located (same form).
After we fill the form with data, we send it to a backend and save already existed object (post by id).
question:
What's the pros and cons of those two cases, when to use each of them?
In the first case you can include the validation of the fields in the time of creation
and you only need to create an insert so one database call.
In the second case you are creating an empty entry that will appear in the grids of an application with no data.
Also if your database has required fields, you have to fill them with default data.
Validation will be more difficult since you need to allow empty ex Mobile in data entry
while phone might be required.
Another problem with this is that that you are basically doing two operations. One if for the Insert of the row and one is for the update of the row
However this methodology is easier to implement the live update of text when typing so any disconnects etc will not lose any data. This methodology is also good for collaboration between two clients using websockets ex inserting the row at the same time.

Breeze EFContextProvider per request and based on parameter?

I have a multi-tenant app in which user can select "current company" after they log in.
There is a DB per company but the model is the same, the workflow is the same, and the controller actions are same....The user can switch companies while being logged in and all actions need to be 'directed' to proper DB.
I know it is possible to customize context creation in EFContextProvider<T> by overriding CreateContext() but how do I pass the extra info (parameter, e.g. CompanyId) that would allow me to create context with correct connection string?
Is this possible?
I find the easiest way is to include the tenant id in a custom HTTP header.
Because the tenant id changes during the session, you probably want to create a custom Breeze ajax adapter (wrap the one you're using now) that sets this header dynamically during its implementation of the ajax method.
On the server you fish the header out of the request.
MAKE SURE YOU ARE VALIDATING USER AND HEADER ON THE SERVER

Different registration forms for different roles. FOSUserBundle

I'm absolutely new of Symfony, and I'm trying to implement a registration form that works only with invitation
but that can redirect two different forms for two different roles.
In practice if I send an invitation for an USER_TYPE1 role the client can only register like USER_TYPE1, if I send an invitation for an USER_TYPE2 the client can only register like USER_TYPE2 (and, of course, assigns the corrispondent role).
Is it possible?
thank you in advance for your help
UPDATE:
I want two different form because one user will be allowed to update file, but will also have to set his position and other important settings. The second user will only allow to download the files uploaded by the first kind of user, and his profile needs completely different information.
I do not have enough reputation to ask for details, but one thing that is not clear in your question is: why do you need 2 different forms? In your question, you mention 2 different roles, but why do you need 2 different forms? If you really need 2 different forms, then you should first:
- create a new form type
- create a new view (twig)
Like Boris suggested, I would keep some kind of token for every invitation sent, and associate an email address, and a role to it. Then modify your registration route so you can pass a token in there, like this:
register:
pattern: /signup/{token}
defaults: { _controller: MyBundle:Registration:signup }
In the registration action of your controller, you created the correct form type and display the appropriate twig, depending on the ROLE associated to the token you just got. And when handling a POST, you check the Token again to see if it matches the email address, and assign the proper ROLE when creating the User.
public function signupAction($token) {
// 1. Get the Token entity matching the $token variable
// 2. Create the correct form type
// 3. Display the correct twig for GET, assign correct ROLE to new User for POST
}
But you can't use FOSUserBundle as-is. You will have to overwrite the registration process. You can read the FOSUserBundle documentation about that.
What's certain is that, for every invitation you send, you should keep a token with a matching email address and ROLE (the role you want to give to that person).

Saving changes to DB made in a webpage

I rewrote the title and content 3 times before posting it, I don't find the right way to ask this :P
I have a page that manage a list of notes, I have a CRUD on that page but the items are created and saved in javascript (using knockoutjs).
I create a new note, I add it to the model in javascript and it show up in the page.
The way Im saving the notes to the database is when I add it to the model, I send it via Ajax (async) to the server. So I have my note on screen and in the database really fast.
I send a note without Id to the server and EF will take care of the Id.
So far so good.
Imagine that I add a note but I dont refresh the webpage, so the note is in the database, is in the javascript model too but in the model it doesn't have the id yet.
I make some changes to the note and yeah, I want to update the note in the database... but... how?
I send my note to the server with the changes, but remember, the item still have no Id so I can't say:
Hey EF, give me the note with the ID == xx and we are going to update that note.
The others properties can be changed on the webpage so I have nothing that identifies the note apart from the Id, who doesn't work here.
I tried this:
Send the new note to the server, insert it on the database, retrieve it again (to pick the Id), send it back to javascript and update the object with the Id. So when I edit, I have the Id. Yeah, but the "save" call need to be sync and that destroy the experience.
Any ideas?
EDIT: The sync options is not that slow at the end but there have to be a async way and meh, the thing of "Insert on database", "Retrieve the last item I inserted" and "return back to the client" is a little hackish.
You could return the id of the new record in your asynch call. If you are using jQuery you can subscribe to the "success" callback and as long as your controller returns a JSON with the id of the new record you could update your model on the client side.
Even with this approach, you will need to have a way to identify the item updated on the client side (which is really the root of your question.) For that you can probably generate a random GUID on the client side, send it to the server when saving, and return it to jQuery when returning the ID so that you can identify the correct element to update on the page.