Unofficial Anvil Firebase Integration v0.1🔥

Good Afternoon!

I’m happy to announce that we are giving back to the anvil community by building an Anvil Firebase Integration.

If you want to build live synced, lightning fast apps without even the need for a server call, or javascript code, this will get you started.
Thanks @meredydd for helping with the third party dependency by the way!
Happy to hear what you guys are building with it.

Klick here for up to date documentation

Disclaimer:

Attention V0 is not Production Ready and in an Alpha Stage - expect breaking changes!:construction::man_construction_worker::fire:

Dependency Link :gear:

Copy this Third Party dependency token into your Dependencies.

U6TW3CSF6MGJ2CZF

Live Example

Anvil Firebase Example

Clone Link for the Live Example: (You need to paste your firestore config credentials to the function init_firebase at line 29 in order for it to work.)

Initialize App📱

Call this function to initialize your Firebase App

If you don’t have a firebase project click this video for more information:

Getting started with Firebase for the web - Firebase Fundamentals

from firebase.firebase_client import initialize_app

project_config = {
      'apiKey': "",
      'authDomain': "",
      'projectId': "",
      'storageBucket': "",
      'messagingSenderId': "",
      'appId': "",
      'measurementId': ""
}

initialize_app(project_config )

Firebase Auth

Import the Authentication Package

from firebase.firebase_client import authentication

Sign up

Sign up a user with simple email password login

authentication.signup_with_email('mark.breuss@markone.at','1234567')

Sign in Email & Password

Log In a user with simple email password login

authentication.sign_in_with_email('mark.breuss@markone.at','1234567')

Sign in Token

You can also use the build in anvil user and securing your database by utitlizing the custom token login.

#you currently need to implement this one yourself
fs_token = anvil.server.call('fs_server_get_auth_token')
authentication.sign_in_with_token(fs_token)

Get User

The following example shows how to retrieve the contents of a single document.

fire_user = authentication.get_user()

Logout

The following example shows how to retrieve the contents of a single document.

authentication.logout()

Firestore Database🔥

Import the Firestore Package

from firebase.firebase_client import firestore as fs

Set a document

Add data to Cloud Firestore | Firebase

This sets and overrides a single document in the collection

doc_ref = fs.doc(fs.db,'test_collection','some_uid')
ret = fs.set_doc(doc_ref,{'key':'some_value','last_update':datetime.now()})

Add a document

This adds a new document to the collection (with an autogenerated uid)

collection = fs.collection(fs.db,'test_collection')
fs.add_doc(collection,{'key':'some_value','key2':'value2'})

Update a document

The following example shows how to retrieve the contents of a single document.

doc_ref = fs.doc(fs.db,'test_collection','some_uid')
fs.update_doc(doc_ref,{'key':'new_value'})

Get a document

Get data with Cloud Firestore | Firebase

doc_ref = fs.doc(fs.db,'test_collection','some_uid')
doc_uid,doc_data = fs.get_doc(doc_ref)

Get multiple documents

Perform simple and compound queries in Cloud Firestore | Firebase

test_collection = fs.collection(fs.db,'test_collection')
q = fs.query(test_collection,[fs.where('key','==','some_value'),fs.where('key2','==','value2')])
documents = fs.get_docs(q)

Listen for realtime updates

Perform simple and compound queries in Cloud Firestore | Firebase


def listener_changed(self,docs):
	'''This is a callback function that is called when data changes'''
  Notification('new data arrived',timeout=5).show

def set_listener():
	'''This sets a listener on a specific part of the collection'''
	test_collection = fs.collection(fs.db,'test_collection')
	q = fs.query(test_collection,fs.where('key','==','some_value'))
	listener = fs.listen_to_docs(q,listener_changed)()

set_listener()

Batch Writes

Transactions and batched writes | Firestore | Firebase

batch = fs.write_batch()
doc_ref1 = fs.doc(fs.db,'test_collection','uid1')
doc_ref2 = fs.doc(fs.db,'test_collection','uid2')
batch.set(doc_ref2,{'batch_key':'value'})
batch.set(doc_ref2,{'batch_key':'value'})
batch.commit()

Transaction

Transactions and batched writes | Firestore | Firebase

doc_ref1 = fs.doc(fs.db,'test_collection','uid1')
doc_ref2 = fs.doc(fs.db,'test_collection','uid2')
#read from doc 1
doc1 = transaction.get(doc_ref1)
#write to doc 2
transaction.update(doc_ref2, { 'new_value': 1234 })

Transaction

Transactions and batched writes | Firestore | Firebase

doc_ref1 = fs.doc(fs.db,'test_collection','uid1')
doc_ref2 = fs.doc(fs.db,'test_collection','uid2')
#read from doc 1
doc1 = transaction.get(doc_ref1)
#write to doc 2
transaction.update(doc_ref2, { 'new_value': 1234 })

Storageđź’ľ

Import the Storage Package

from firebase.firebase_client import storage

Upload Media

Upload files with Cloud Storage on Web | Firebase Storage

#1. get any anvil blob media image
file = anvil.URLMedia("https://anvil.works/ide/img/banner-100.png")
#2. define a storage path
ref = storage.ref('images/test1.png')
#3. upload file
storage.upload_media(ref,file)

Download Media URL

ref = storage.ref('images/test1.png')
url = storage.get_download_url(ref)
#use this url as source of an anvil image component for example

Analyticsđź“Š

from firebase.firebase_client import analytics
analytics.log_event('testevent')
13 Likes

This is super exciting! The real time updates are one area I’m looking forward to playing with.

2 Likes

Nice - let me know if you run into any hurdles! :ok_hand:

I’m going to show my ignorance here…

Having never used (indeed heard of) firebase, what does it do for me if I’m already using Anvil? A quick perusal of the website looks like its Google’s attempt to do a heap of stuff Anvil already does.

I’m sure that’s not the case or you wouldn’t have gone to the time and trouble to write this but it’s not obvious (at least to me) from the website and I don’t really have the inclination to wade through their demos and docs.

2 Likes

Hi @owen.campbell,

I’m not owning any Alphabet stock, thus I’m not gonna try to sell their product here.
Firebase, is a BaaS and this plugin is mainly focused on Firestore the NoSQL Database.

But, try to write an application in pure anvil that is:

  • live synced
  • Is so fast that you are spinner free
  • scales to a hundred million requests per day with ease
  • Automatic Sharding
  • works offline/online with automatic syncing
  • stores images on a global CDN
  • Working across plattforms
    (what if you build a native Android app in addition to your anvil app? Rest Endpoints & custom JWT Auth :face_with_spiral_eyes:)

Saying that as a true anvil-believer, at least for now this can hardly be achieved in pure anvil.

Of course those requirements do not apply for most personal cases, but for someone building a scalable SaaS buisness this should be on your mind when choosing your database.

thanks for pointing that out by the way!

Mark

10 Likes

Thank you! Level of ignorance now reduced slightly which is always good.

5 Likes

Check out https://fireship.io , he pretty much does “insert framework/stack here” + FireBase tutorials.
I don’t have any need for it now, but if I wanted to scale the lazy way I would probably use it :sweat_smile:

He also has a pretty killer YouTube channel called Fireship , if your into that kind of thing. (short videos on modern app development)

3 Likes

Can’t wait to play with it and see it grow!

1 Like

Thank you, looking forward eagerly to trying this!

1 Like

Hi all,

We just shipped the stable version 0.4 which includes more powerfull serialization (mostly datetime objects), stablity improvements and the ability to call cloud functions.

Link to official Docs:

Also - just out of curiosity, does anyone use this dependency in production?

Happy coding🥳
Mark

5 Likes

Thank you Mark. I’m still looking for a project that needs this for production …perhaps I’ll just choose to use it for some in house production solutions next… I’ll let you know as soon as it gets put to the test.

1 Like

I want to! but this scared me away LOL

Rigthfully so!
However - we invested quite some time into this dependency and V0.4 is stable and we are using this library now ourselfs for one of our production apps.

So we won’t introduce any breaking changes for this dependency.:wink:

6 Likes

Thank you for the confirming the state @mark.breuss and Merry Christmas by the way! :slight_smile:

1 Like

I replaced all the database functionality in a little app used to sign up students for recital performances at Rockfactory, with this dependency. It’s a very low bandwidth app, but serves as a legit proof of concept. Thanks for a great and easy to use integration - the live automatic syncing is really cool!

3 Likes

Automatic syncing of data entered while offline is also a seriously useful feature that comes for free, and saves an enormous amount of potential work where that’s a requirement. I expect to use this integration for lots of projects in the future!

1 Like

Wow, I missed this when you first announced it, but now I’m excited! This gives me hope that I could stay with Anvil and retain performance if usage of my app scales like I hope it will over the next year or two.

Have you considered open-sourcing it, like on GitHub? That would definitely give me greater comfort as far as using it in production.

2 Likes

@nickantonaccio great to hear it works out for you :ok_hand:

@hugetim
I think the dependency will most likely end up beeing open sourced.

So far it just wasn’t worth the hassle to properly open source it - to be honest.
But if more people start using/show interest in it, we will dedicate some time to open source it on github. :ok_hand:

4 Likes

Here’s a version of the example app cleaned up to my OCD-ish liking. :slight_smile: Mostly, I hid or commented out the parts that are not used in the actual demo:
https://anvil.works/build#clone:GIFR6NZ4TBG3X5FV=H6LN5TCYYBIFK4HUIOXA76XE

Also, some docs feedback: the “Getting started with Firebase for the web - Firebase Fundamentals” video didn’t tell me how to create a Firebase project as I was expecting it to (though that turned out to be pretty self-explanatory). Instead, the contents were pretty redundant to your docs, with the one exception being the reassurance that it really is safe to expose that project_config info on the client side.

Hi @hugetim,

thanks for the feedback!
I cleand up the docs and added a note that security is indeed all enforced via security rules. (They act similar to row level security on postgres)

1 Like