Chattn

Who you reall chattin mate?! Jun 08, 2019 Tags: Javascript Vue Vuex Firebase

Chattn is live

They say the best way to learn something is to throw yourself into the deep end. I didn’t really have any grand idea for a project app, so I did what any other developer would do…just recreate an existing product. Twitter is always a good goal, I created a very basic twitter clone with React/Redux but never hosted it but decided I would do so with this one. I chose to create this with Vue because I was always interested in it but never got around to giving it a spin as I usually stuck with React. I wanted to get out of my comfort zone and try something new. Vue clicked fairly quickly which is in large part to understanding React and having general knowledge of Javascript and reactive UI frameworks and paradigms.

I wanted this unlike my React/Redux version of Twitter to go past surface level features of simply posting and displaying said posts, that’s pretty simple and tired and everyone is doing it. So I decided to add do more adding feature by feature. So I added features that I liked from Twitter and really thought about implementation, with this project I really wanted to focus on the backedn which in this case was Google’s firestore, well I originally went with Firebase, but wanted to try Firestore mostly because it was in my face on the Google dashboard “Try our next gen real time database Firestore!” Firestore follows many of the same paradigms as other NoSQLs so getting up and running was pretty easy, doubly so because of Google’s great documentation, and its similarities with its brother Firebase.

Speaking on Vue, this is a fantastic little framework and I’m pretty sure I enjoy working on it more than React. It feels like it sits right between React and Angular as far as layers and components (see what I did there?) that are included in it. I really appreciate you can slowly implement Vue into a project whereas React is an all in affair. I haven’t really messed with Angular much so I won’t comment on it in any meaningful capacity. I will say that Vuex is much easier to reason about than Redux but I will also fully admit that it might because I “know” Redux so any other flavor of the flux architecture just clicks.

As I previously stated, I learned Vue/Vuex as I worked on this project so looking through branches it becomes very apparent that I learn something new and implement it, on this project I didn’t create tests, which I full admit is my shortcoming as a developer and need to be much more dilligent on writing them before I start coding, there are no downsides to running tests, so always write them!

neat

Some of the features I’m most proud of are base64 image implementation so that I could have image previews before the user posts, I rewrote the image upload feature a few times. In the initial version, the user would select their image and it would upload to Google storage immediately after selecting it, leaving the user without the ability to cancel or change what image they used with their post. That was my naive implementation and it took me several days to come up with the base64 version. Admitted despite knowing of Base64, it took a while for it to occur to me to utilize it. Because of how I initially assumed twitter image posting worked I couldn’t think of a better way to do everything. The next thing I want to tackle is better handling of the moment the image is loading after a user hits post. I am not a fan of that second or two of waiting for the image to laod. There are several methods to fix this, the easiest and most straightforward is using Google Functions to resize/quality reduce the image so it loads quicker. This is the approach I’ve been working on but it’s proving to be frustrating as when a post is created, the image is sent to the Google storage and a permanent link is generated and that link is appended to the post’s imageURL field, THEN Google function kicks in and does imageMagicks on it but it does not generate a permanent link for the newly created image…so I cannot appened it to the imageURL field.

My other idea for tackling this is to get the dimensions of the user’s image and creating a placeholder container that is of the supplied dimensions then let the actual image take its place once the image has loaded, I thought of this approach due to wanting to better implement lazy loading where I wanted to use the same idea of using the image’s dimensions to create a temporary container (as well as taking the user image’s dominant colors to color the container) Oop

Another feature I was proud of was more backend related but I spent a week agonizing on how to trigger images being deleted from the storage bucket when a user deleted their post, and was getting frustrated with being on the cusp of figuring it out but having to wait to test my firestore functions as they needed to be uploaded to the function module on Firebase.

One thing I definitely shouldn’t have done was that I did all the CSS from scratch instead of using a library like Bulma or my new favorite, Tailwind. In hindsight this was both a good thing and a terrible mistake, it was a good thing because I really had to think of implementation and I learned how Vue handles CSS interactivity. The cons were…I was basically doing everything from scratch, so everything you see and are interacting with was all me no help from libraries or baked in functions from a CSS framework. I tried to stick with the BEM methodology to the best of my abilities but I also wanted to mess with the various ways Vue handled CSS so it was getting harder, that and I would do naive implemenetation to figure out if I’m going in the right direction

One of my biggest challenges I overcame was finally truly breaking my SQL mindset when working with NoSQL and embracing repeat data. What finally made it click for me was looking at data usage on database dashboard and realized I was making multiple requests for user data, and honestly even before that it just made no sense how often I was requesting data for simple things. A great example would be the bookmark feature I just recently added. They are stored as a subcollection based on the users’ collection documents. The necessary information from each bookmark post is stored in this collection which in this case are: username, user id, profile picture, post image if there is one. This data is already present in the database but if I didn’t duplicate it I would have to query it from that particular user’s post collection. You can see how inefficient this becomes if the user were to have say 60 bookmarks, the database would have to query the all 60 users’ post collection.

There are still more features I want to add and I have an idea on how to go about them. I need to implement better display of notifications, right now it’s just plain text in green but this is just a toy project and I don’t want feature creep to set in and suddenly I’ve been working on it for months upon months (which technically I already have, I started this in like April or May…). I’ve added some neat features so far and really need to refactor many others, but before I add anymore I need to add tests to this.

Features I haved added so far are: Likes, posting, comments, image upload, profile creation and updating, profile photo and profile banner, bookmarks, authentication. At the very least I want to add in the ability to make an account private because it seems like a nice challenge.

Lastly I have yet to add follower/following not because I didn’t know how to or anything of the sort, I created a decent implementation using PostgreSQL back when I made Drubbble. I definitely understand the underlying of how to implement it with a NoSQL, so implementation isn’t the reason. Honestly the reason is simply because…it would introduce a bunch of feature creep haha, because I can’t stop at simply following/followers, I’d want to add the ability to block, having block automatically unfollow an account, and a few things which I imagine would mean I’m yet spending another couple months on the project on the minimum side. With that stated…I’m probably still gonna add it.