
Firebase as a React Hook - dsaffy
https://pragli.com/blog/firebase-as-a-react-hook/
======
ng12
This is the kind of stuff that makes me really love hooks. I've been able to
refactor so much code cleanly -- complicated data fetching logic, ugly parts
of my Redux store, confusing HOCs, window.setInterval spaghetti, etc. Really
excited to see more high-level hooks get published.

~~~
neals
I tend to be "behind" on the latest and greatest in my frontend Dev work.
Usually picking stuff up 1 or 2 years after the initial hype.

I do have to say that I am eyeballing hooks for solving HOCs, which have been
popping up more and more in my applications.

~~~
davnicwil
This is a great strategy in many ways, because after a couple of years the
'this solves every problem' hype has mostly settled and the good, practical
uses for the newer pattern are usually fairly clear from consensus.

I'd say use this to your advantage with hooks. They're amazing and much nicer
for some things, but don't go in thinking of HOCs, render props, even class
components with lifecycle methods, as something that _should_ be replaced
entirely because hooks are universally better at everything they can do.

The latter are indeed cleaner than hooks, simpler, less hassle, etc in many
situations - and truly, honestly, a lot of the time it's nothing more than
personal preference anyway.

~~~
ng12
I find that most the most common situation where a class component seems
simpler is because the component is broken -- e.g. someone took a shortcut and
assumed a prop would never change, made assumptions about the comparisons
needed in `componentDidUpdate`, or didn't handle race conditions.

Personally I'm at the point were I think hooks have been vetted enough that
I'm comfortably recommending functional components in all situations. I teach
a short "Intro to React" workshop and at this point I don't even mention class
components except for a very brief FYI at the end, and even that is mostly in
case developers encounter class components in Stack Overflow.

~~~
davnicwil
I mostly agree with this, and I also prefer using functional components
whenever possible, but I think there are still situations where the mental
model of class components with their lifecycle hooks is a much better fit for
a problem, at least for me.

These tend to come up rarely, but it'll be things like super imperative side-
effect controlling components that, for instance, hook into non-React
libraries (3D graphics libs, or 3rd party vanilla JS widgets, for example) via
escape hatches.

In those scenarios, you're very much in imperative mode, as opposed to
declarative mode. Functional components and hooks excel at declarative mode,
which most web app code is. Class components with their implicit statefulness
and lifecycle hooks model however excel at imperative mode, so when you need
that, they are for me the better solution.

------
nicoburns
I'd highly recommend people to stay away from Firebase. The querying options
are really lacking. You'll likely get much better performance for much
cheaper, and easier to develop for with a cheap postgres instance.

~~~
friedman23
I don't mind using SQL (and I would actually prefer it) but what I want to
avoid is having to build an api middleware with auth for my personal projects.
Are there any alternatives to firebase you would recommend that would allow me
to use SQL without having to build out an API?

~~~
elitan
I was in the exact same position as you one year ago. Then I found Hasura
([https://hasura.io](https://hasura.io)) and built Nhost
([https://nhost.io](https://nhost.io)). While building Nhost I always had
Google Firebase in mind regarding how good they are for the developer
experience.

------
danappelxx
In one of the examples, the author fetches results from Firebase, and then
sorts them in the browser. I'm not huge on Firebase, but aren't there methods
([0]) to do this on the database, where it'd be much faster and wouldn't waste
client cpu?

If this is the case, then this is a bit of faulty abstraction - your database
queries are going to be more than just 'select * from <>'. I'm sure there's a
way to accomplish this with react hooks without sacrificing elegance for
performance.

[0]:
[https://firebase.google.com/docs/reference/js/firebase.datab...](https://firebase.google.com/docs/reference/js/firebase.database.Reference.html#orderbyvalue)

~~~
SkyPuncher
Some of this comes down to cost optimization.

I believe Firebase charges per record returned. Having an index and sort query
doubles the costs compared to client side sorting on the index.

~~~
danappelxx
But at the same time, what if you want to filter records? Doing it on the
Firebase side saves both time and money.

------
sjroot
See also: React Firebase Hooks

[https://www.npmjs.com/package/react-firebase-
hooks](https://www.npmjs.com/package/react-firebase-hooks)

~~~
jeffgreco
I've been using a lot of this library with Firestore and it's great.

------
tracker1
Cool, I would suggest supporting it as a template string processor, that way
you can escapee (encodeURIComponent) the key values passed in more easily.

    
    
        const value = useDbDatam`/sometype/#{someId}/foo`;

------
jcampbell1
Is this bit of code considered kosher javascript?

{[path]: payload}

I don't think I have seen this before... it looks like a short cut to get a
dynamic key. I can't decide whether I like it or hate it. It is new to me, and
it seems like typescript won't understand it. You will also have a bad time if
path === 'constructor'.

~~~
wrkronmiller
Yes, it creates an object with key as the value of path and value the value of
payload. If path=1, payload=2, this call would make the object {‘1’: 2 }

~~~
jcampbell1
That is what I thought, and if path = ['foo','bar'] and payload = 2, it makes
{'foo,bar',2}.

It is for sure making max use of dynamic programming. Typescript accepts it as
{[path as any]: payload} which is pulling ejection lever on typescript.

Glad I learned something new from this.

~~~
PudgePacket
It's just a nice quality of life improvement compared to

    
    
      const obj = {};
      obj[foo] = 10;

------
pininja
Looks good! I’m going to try it out on a project. Do you have any ideas for
hook designs to write/update firebase data?

~~~
dsaffy
We don't use hooks for doing writes / updates... I'm curious if there's a
clever way to do that. Maybe the useDbData hook could also return a write
callback?

------
evolveyourmind
I think you have a typo in the second code example:

    
    
      let students = useDbDatum(`classes/${classUid}/students`);
      let uids = Object.keys(students || {});
      let paths = studentIds.map(id => `students/${id}/name`);
    

studentIds on line 3 should probably be uids

~~~
dsaffy
Yup... fixed!

------
kevindetry
There is also Google's own library for that:
[https://github.com/FirebaseExtended/reactfire](https://github.com/FirebaseExtended/reactfire)

------
julbaxter
Does someone know an equivalent for Firestore?

~~~
jeffgreco
React Firebase Hooks (mentioned elsewhere in the thread) works great with
Firestore: [https://www.npmjs.com/package/react-firebase-
hooks](https://www.npmjs.com/package/react-firebase-hooks)

