can i upload posts with the same auto id? swift 4 firebase - iphone

Is it possible to upload a post to firebase to 3 different locations and with the same autoId sense the posts is exactly the same. So I have just managed to let users to delete their posts, but when they upload the posts it is actually uploaded to 3 different locations like this
// this uploads the "post" to a global page
Database.database().reference().child("posts").childByAutoId().setValue(postObject)
// this uploads the "post" to a specific country page the user have choosen
Database.database().reference().child("AlbaniaPosts").childByAutoId().setValue(postObject)
// this uploads the "post" to the users uid so all their posts will be shown at the profile page
Database.database().reference().child(uid!).childByAutoId().setValue(postObject)
And when they are saved in firebase they are saved as different childByAutoId so I was wondering if it is possible to save them all in the same childByAutoId ID.
So that if the user delete's a specific post then I can search for the AutoId they deleted and delete it from all countries and profile page and the global page, but I can't right now sense I upload the post in diffrent Id's
So if it is still hard to understand my question here is an image of my database
As you can see the posts are exactly the same, but they are saved in different AutoId's
Goal? My goal is to set the same id for the post when they are uploaded at all 3 locations.
help would be very much appreciated.
thanks for your time.

Yes you can do this. The problem is with how you are uploading the information. Get one key and reuse it. Like this:
let key = ref.child("posts").childByAutoId().key // use this key for all uploads
// this uploads the "post" to a global page
Database.database().reference().child("posts").child(key).setValue(postObject)
// this uploads the "post" to a specific country page the user have choosen
Database.database().reference().child("AlbaniaPosts").child(key).setValue(postObject)
// this uploads the "post" to the users uid so all their posts will be shown at the profile page
Database.database().reference().child(uid!).child(key).setValue(postObject)
Now all posts will be uploaded using the same key. I did childByAutoId() on "posts" but you can do it on any location. The reason you are getting different keys is because they are determined by the time you request them. Since you're requesting them at different times you're getting different keys.
Additionally, I think you might want to carefully think about how you want to access and modify data within your app. For example modifying one post requires editing the data in three separate locations. This problem could be solved by the use of cloud functions. Another option would be to just copy the "key" to things like "AlbaniaPosts", then you can query the keys for all posts under "AlbaniaPosts" you can use the keys to load the full post from "posts". You'd still need cloud functions to copy and delete the key around your database. Let me know if you have any questions.

Related

Get Firebase Dynamic Link Data from String Input url Flutter

Dynamic links work great for 98% of our users. However, there are still a group of users which have difficulty with them or do not know how to use them.
I want to add a feature which would let users paste their link into the app, and then we extract the data from the link and handle it normally. This will also serve as a backup for when the links are down or misbehaving. It will also allow our customer service team to get data from a link when customers share them with us.
The problem is, there doesn't seem to be a way to manually pass in a dynamic link to retrieve the dynamic data.
Does anyone know how this can be achieved?
Here is my attempt at your question.
I am assuming what you mean by the dynamic data is the underlying deeplink along with the parameters associated with the deeplink.
void dynamicLinkToDeepLink(String dynamicLinkString) async {
final details = await FirebaseDynamicLinks.instance.getDynamicLink(Uri.parse(dynamicLinkString));
// your deep link can be accessed as follows
details!.link;
}
You have to safeguard the above code as you see fits when you use it. You will have to wrap FirebaseDynamicLinks.instance..... with a try catch block and you will also have to check if the value of the returned link is not null before acccessing details!.link

REST: nested resource url when you don't want the parent ID visible

I read that the route for getting a nested resource in REST should look like this
/articles/:articleId/comments
The owner (:articleId) of the child resource will be visible.
But what if you have an owner that you don't want the client to know about?
For example, let's say I have an app where users have anonymous posts. I wouldn't want other users to see the client fetching the post by /users/123/post/321 because users could identify who wrote the post from the id and it wouldn't be anonymous.
Is the id necessary? Is it ok to instead do /users/posts/321 if all posts have a unique id?
There are no actual requirements for the URL format. It can be whatever you'd like it to be.
If it were me, I would use simply /posts/321 and leave users out of it, since a particular user isn't specified in your URL at all. I think that's the clearest way to handle it in your case.

Structuring Firebase database like Snapchat

I've been working on a snapchat clone as a way to learn how to use firebase.
I am currently stuck on how to best structure my data so that I could mimic a simple version of Snapchat.
What I'd like to do in my simplified version:
Send a picture message to multiple users
Post the picture message to a "story" feed where all my friends can see it.
I don't need anything more really. I'm not trying to implement snapchats current feature of being able to send text messages or anything like that. I just want to send pictures to friends and also post them to a public feed.
I've structured my data like this:
And Breaking it down:
Users:
Friendships between users structured like this:
Individual messages structured like this:
An index for conversations like this:
Now I've seen plenty of posts on stack and online for structuring messages in chat applications. What I'm stuck on is how to structure my DB so that a message can be sent to a user so that only that users receiving users see it.
I've been reading the firebase docs and I know I should be denormalizing data so that I can read data more efficiently, but I can't really wrap my head around the best way to do so with Firebase.
In my current implementation of user-messages, I would have to implement a check in my code to see if the message was sent by my user, and then prevent the user from seeing it. Ideally only the person who the message was sent to should see the image. (just like snapchat)
Any suggestions on how to do so?
Do I need to have some reference to the chat/message in the user tree?
The question appears to be
how to structure my DB so that a message can be sent to a user so that
only that users receiving users see it
There are many 'directions' but here are two.
1) Manually 'tell' each user about a pic
users
uid_0
pics_for_me
pic_0
url: "http://...."
pic_1
url: "http://...."
my_users
uid_2: true
uid_1
pics_for_me
my_users
uid_0: true
uid_2: true
With this structure, uid_1 has two users they want to share pics with (uid_0 and uid_2) so when it comes time to share the pic, read the my_users node, iterate over it, and store a link to the pic in that users respective pics_for_me node. Obviously you could store other data such as who it's from etc. When uid_0 logs in, read the pic_for_me node and view the pics, perhaps deleting it when done.
2) Observe a node for pics for a user
users
uid_0
name: "Henry"
uid_1
name: "Joe"
all_pics
pic_0
for_user: "uid_0"
url: "http://..."
in this scenario, uid_0 logs on and adds a query to all_pics for any for_user that contains their user id. This would work for a 1-1 situation where the pic is meant for one user. If you want multiple users to get a pic then...
all_pics
pic_0
uid_0: true
uid_1: true
and when a user logs in add a query to all_pics where that users uid is true, and then any time a picture is added that has a child of their uid, they will receive an event.

Restful Collections - how to either remove OR delete items

I read quite some stuff about RESTful API Design.
But when it comes to the implementation, it wasn't that easy anymore.
I got stuck at the following problem:
Assume the following 2 endpoint:
/api/v1/users/:id
/api/v1/users/1/friends/:id
As we all can see, friends is a collection of the resource user.
A user can have n-friends in his friendslist (by standard this would be many to many, but for now, let's assume this to be one to many).
Okay, now i want to REMOVE a user (id=3) from the friendslist of user 1 by doing the following HTTP-Request:
DELETE api/v1/users/1/friends/3
And this is where i got stuck - either the request deletes the whole user resource which has id = 3 or removes the resource from the collection. Because both would be valid Restful implementations i think.
So the question is:
How to remove an item from the collection without deleting the original resource
I hope that this question is no duplicate - but i did google a lot to find the answer. Maybe i don't know the related technical term to find some pleasing results...
Thanks in forward.
The approach to REST looks fine but that really only speaks to path format and HTTP verb. The problem must be in your application code or app routes.
I think it is better that DELETE api/v1/users/1/friends/3 would be used to delete user 3, just like DELETE api/v1/users/1 would be used to delete user 1.
To remove just user 3 from being a friend of user 1 I would use DELETE api/v1/users/1/friends and specify a filter to only remove friends with the id of 3.
DELETE api/v1/users/1/friends without a filter would remove all friends of user 1.
Likewise to add friends of user 1 I would use PUT api/v1/users/1/friends and specify the ids of the friends to add.

Rest API, relationships and subsets

I have some questions about Rest API and relationships.
I know the questions of relationship is always tricky with Rest.
I have some users, posts (created by user), relationships between users (imported from fb), interactions on posts (created by user) and users can like a post.
User can create a posts which will be seen only by others users who have a relationship (up to 2 jump, like friends of friends) with the poster and then can create interactions on the post.
We do a filtering on the backend based on your authentification and just do the magic on /posts which will return you the list of post that you can see.
It feel a bit funky to me because it make the same endpoint (/posts) will return different set of data based on the current user. We could of course pass a parameters (?viewable_by_user_id=:id) to reflect it a bit more, but I wonder if I can do anything to improving caching.
I'm thinking of improving our API to a v2 with this endpoints:
GET/PATCH/DELETE /users/:id
POST [post] /posts: create a post (using current auth user as the owner of the post)
or
POST [post] /users/:id/posts: create a post for this user
GET /users/:id/posts : get posts created by the user
GET /users/:id/stream : get posts "viewable" by the user (this is the one I'm strugeling with)
or
GET /posts?viewable_by_user=:id
GET /users/:id/like : get posts liked by the user
POST [post_id] /users/:id/like : like a post
POST [interaction] /posts/:id/interactions : create an interaction on the post for the current user
GET /posts/:id/interactions : get post's interactions
GET/PATCH/DELETE /interactions/:id
Any thoughts on how I could make the path reflect a bit more the relationship?
I've thinking on creating an endpoint for relationships but seem a bit to complex to maintain (users don't create relationship manually, we pull them from fb)
Thank you for any feedback, and let me know if my question is too ambiguous or irrelevant.
What if you think of it as this: (Note that I just like putting "posts" first since it tells what and then the restrictions go to the right of that. You may like the other order.)
GET /users/posts/<viewer>/<creator>
This gives some degenerate cases:
GET /users/posts/<me>/<me>
to get all the posts I have created
GET /users/posts/<me>
to get all the post from all other users
GET /users/posts/<me>/<stranger>
would return nothing because I am not allowed to see the stranger's posts
GET /users/posts/<me>/<friend>
would return the posts from my friend.
NOTE: In all cases, all posts returned are those allowed to be seen