We are pleased to announce that we are taking our first steps towards open sourcing our client libraries. By making our SDKs open, we're aiming to show our commitment to greater transparency and to building a stronger developer community. To help further that goal, we'll be using GitHub as a core part of our own toolchain to enable all of you to contribute as well. As you find issues in our code, from inconsistent style to bugs, you can file issues through the standard GitHub issue tracker. You can also find our project in the Google Open Source directory. We're really looking forward to your pull requests!
We're starting by open sourcing several products in our iOS, JavaScript, Java, Node.js and Python SDKs. We'll be looking at open sourcing our Android SDK as well. The SDKs are being licensed under Apache 2.0, the same flexible license as existing Firebase open source projects like FirebaseUI.
Let's take a look at each repo:
https://github.com/firebase/firebase-ios-sdk
With the launch of the Firebase iOS 4.0 SDKs we have made several improvements to the developer experience, such as more idiomatic API names for our Swift users. By open sourcing our iOS SDKs we hope to provide an additional avenue for you to give us feedback on such features. For this first release we are open sourcing our Realtime Database, Auth, Cloud Storage and Cloud Messaging (FCM) SDKs, but going forward we intend to release more.
Because we aren't yet able to open source some of the Firebase components, the full product build process isn't available. While you can use this repo to build a FirebaseDev pod, our libraries distributed through CocoaPods will continue to be static frameworks for the time being. We are continually looking for ways to improve the developer experience for developers, however you integrate.
Our GitHub README provides more details on how you build, test and contribute to our iOS SDKs.
https://github.com/firebase/firebase-js-sdk
We are excited to announce that we are open sourcing our Realtime Database, Cloud Storage and Cloud Messaging (FCM) SDKs for JavaScript. We'll have a couple of improvements hot on the heels of this initial release, including open sourcing Firebase Authentication. We are also in the process of releasing the source maps for our components, which we expect would really improve the debuggability of your app.
Our GitHub repo includes instructions on how you can build, test and contribute.
Node.js: https://github.com/firebase/firebase-admin-node
Java: https://github.com/firebase/firebase-admin-java
Python: https://github.com/firebase/firebase-admin-python
We are happy to announce that all three of our Admin SDKs for accessing Firebase on privileged environments are now fully open source, including our recently-launched Python SDK. While we continue to explore supporting more languages, we encourage you to use our source as inspiration to enable Firebase for your environment. (And if you do, we'd love to hear about it!)
We're really excited to see what you do with the updated SDKs - as always reach out to us with feedback or questions in the Firebase-Talk Google Group, on Stack Overflow, via the Firebase Support team, or now on GitHub for SDK issues and pull requests! And to read about the other improvements to Firebase that launched at Google I/O, head over to the Firebase blog.
It's been an exciting year! Last May, we expanded Firebase into our unified app platform, building on the original backend-as-a-service and adding products to help developers grow their user base, as well as test and monetize their apps. Hearing from developers like Wattpad, who built an app using Firebase in only 3 weeks, makes all the hard work worthwhile.
Heading to WWDC this year? Join us at the Firebase + Fabric party on June 5th as we celebrate with the top iOS developers from around the world.
We’re excited to throw our very first iOS developers party at this year’s conference - co-hosting with our teammates at Fabric who’re also deeply passionate about mobile development. If you’re going to be in town, join us for a night to mingle with other developers, meet engineers and PMs from the Firebase and Fabric team, showcase your latest app, or whatever strikes your mood.
We look forward to hearing about all the cool stuff you’ve been working on.
Tickets are limited so request your invite today!
Google I/O is rapidly sneaking up on us. I hope those of you attending have your bags packed by now, and those joining on the live stream have started marking the sessions you want to see. It's quite a lineup.
first_open
in_app_purchase
firebase.initializeApp()
// DON'T DO THIS ANYMORE! switch (location.hostname) { case 'myapp.com': firebase.initializeApp(prodConfig); break; case 'myapp-staging.com': firebase.initializeApp(stagingConfig); break; default: firebase.initializeApp(devConfig); break; }
script
<!doctype html> <html> <body> ... <!-- Import and initialize the Firebase SDK --> <script src="/__/firebase/3.7.4/firebase-app.js"></script> <script src="/__/firebase/3.7.4/firebase-auth.js"></script> <script src="/__/firebase/init.js"></script> <script> // The Firebase SDK is ready to rock! firebase.auth().onAuthStateChange(function(user) { /* … */ }); </script> </body> </html>
firebase serve
/__/firebase/{VERSION}/firebase-{app,auth,database,messaging,storage}.js
/__/firebase/{VERSION}/firebase.js
/__/firebase/init.js
/__/firebase/init.json
init.js
3.6.0
firebase deploy
firebase login --reauth
firebase setup:web
firebase-tools
$ npm install --save firebase-tools@^3.6
const fbcli = require('firebase-tools'); const fs = require('fs'); // by default, uses the current project and logged in user fbcli.setup.web().then(config => { fs.writeFileSync( 'build/initFirebase.js', `firebase.initializeApp(${JSON.stringify(config)});` ); }); // alternatively, you can pass project or token information fbcli.setup.web({ project: 'my-custom-project', token: process.env.FIREBASE_TOKEN });
import firebase_admin from firebase_admin import credentials cred = credentials.Certificate("path/to/service.json") firebase_admin.initialize_app(cred)
firebase_admin.initialize_app()
uid = "some-uid" additional_claims = { "premiumAccount": True } custom_token = auth.create_custom_token(uid, additional_claims)
decoded_token = auth.verify_id_token(id_token) uid = decoded_token["uid"]
Firebase Cloud Messaging (FCM) is a cross-platform messaging solution that lets you reliably deliver messages to your apps and sites. It provides two types of messages:
Data Messages are a great way to build custom notifications, when the layout provided by notification messages is not enough, or to trigger background operations like a database sync or the download of additional content (image attachments, emails, etc.)
The best way to trigger a background operation from a data message is by using the Work Manager to schedule your operation at a point when it's best for the user (like avoiding extra work when the battery is very low, or when the CPU is already heavily used by other foreground applications).
To get started, check out the Android O Developer Preview site where you will find instructions on downloading and installing the required SDKs. For Firebase Development, you'll also need to install the Firebase SDKs for Android. Be sure to use version 10.2.1 or later for Android O development.
Android O introduces new background processes optimizations, which make the use of JobScheduler (or wrapper libraries like the Work Manager) a requirement for long-running background operations. Due to these optimizations, the FCM (hence GCM as well) callbacksonMessageReceived()and onTokenRefresh() have a guaranteed life cycle limited to 10 seconds (same as a Broadcast Receiver). After the guaranteed period of 10 seconds, Android considers your process eligible for termination, even if your code is still executing inside the callback. To avoid your process being terminated before your callback is completed, be sure to perform only quick operations (like updating a local database, or displaying a custom notification) inside the callback, and use JobScheduler to schedule longer background processes (like downloading additional images or syncing the database with a remote source).
onMessageReceived()
onTokenRefresh()
@Override public void onMessageReceived(RemoteMessage remoteMessage) { if (/* Check if data needs to be processed by long running job */ true) { // For long-running tasks (10 seconds or more) use the Work Manager scheduleJob(); } else { // Handle message within 10 seconds handleNow(); } } /** * Schedule a job using the Work Manager. */ private void scheduleJob() { WorkManager.getInstance().enqueue( new OneTimeWorkRequest.Builder(MyWorker.class).build()); } /** * Perform and immediate, but quick, processing of the message. */ private void handleNow() { Log.d(TAG, "Short lived task is done."); }
We hope this helps you understand how to use FCM to schedule long-running background operations. This solution greatly helps Android to preserve battery life and ensures that your application works fine on Android O. In case you have any questions don't hesitate to ask us on our support channels.
#standardSQL SELECT event_dim FROM `firebase-analytics-sample-data.android_dataset.app_events_20160607` LIMIT 50
#standardSQL SELECT event_dim FROM `firebase-analytics-sample-data.android_dataset.app_events_20160607` WHERE event_dim.name = "round_completed"
Error: Cannot access field name on a value with type ARRAY<STRUCT<date STRING, name STRING, params ARRAY<STRUCT<key STRING, value STRUCT<string_value STRING, int_value INT64, float_value FLOAT64, ...>>>, ...>> at [2:17]
UNNEST
#standardSQL WITH data AS ( SELECT "primes under 15" AS description, [1,2,3,5,7,11,13] AS primes_array) SELECT * FROM data
#standardSQL WITH data AS ( SELECT "primes under 15" AS description, [1,2,3,5,7,11,13] AS primes_array) SELECT description, prime FROM data CROSS JOIN UNNEST (primes_array) as prime
primes_array
description
prime
SELECT *.
CROSS JOIN
#standardSQL WITH data AS ( SELECT "primes under 15" AS description, [1,2,3,5,7,11,13] AS primes_array) SELECT description, prime FROM data, UNNEST (primes_array) as prime
#standardSQL WITH data AS ( SELECT "primes under 15" AS description, [1,2,3,5,7,11,13] AS primes_array) SELECT description, prime FROM data, UNNEST (primes_array) as prime WHERE prime > 8
#standardSQL SELECT event.name, event.timestamp_micros FROM `firebase-analytics-sample-data.android_dataset.app_events_20160607`, UNNEST(event_dim) as event WHERE event.name = "round_completed"
params
#standardSQL SELECT event, event.name, event.timestamp_micros FROM `firebase-analytics-sample-data.android_dataset.app_events_20160607`, UNNEST(event_dim) as event, UNNEST(event.params) as event_param WHERE event.name = "round_completed" AND event_param.key = "score" AND event_param.value.int_value > 10000
#standardSQL SELECT user_dim.app_info.app_instance_id as unique_id, MAX(user_prop.key) as keyname, MAX(user_prop.value.value.string_value) as keyvalue FROM `firebase-analytics-sample-data.android_dataset.app_events_20160607`, UNNEST(user_dim.user_properties) AS user_prop WHERE user_prop.key = "language" GROUP BY unique_id
#standardSQL SELECT keyvalue, count(*) as count FROM ( SELECT user_dim.app_info.app_instance_id as unique_id, MAX(user_prop.key) as keyname, MAX(user_prop.value.value.string_value) as keyvalue FROM `firebase-analytics-sample-data.android_dataset.app_events_20160607`, UNNEST(user_dim.user_properties) AS user_prop WHERE user_prop.key = "language" GROUP BY unique_id ) GROUP BY keyvalue ORDER BY count DESC
#standardSQL SELECT user_dim, event, event.name, event.timestamp_micros FROM `firebase-analytics-sample-data.android_dataset.app_events_20160607`, UNNEST(event_dim) as event, UNNEST(event.params) as event_param, UNNEST(user_dim.user_properties) as user_prop WHERE event.name = "round_completed" AND event_param.key = "squares_daubed" AND event_param.value.int_value > 20 AND user_prop.key = "elite_powers" AND (CAST(user_prop.value.value.string_value as int64)) > 1
tools:node
"remove"
<provider android:name="com.google.firebase.provider.FirebaseInitProvider" android:authorities="${applicationId}.firebaseinitprovider" tools:node="remove" />
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" package="your.package" >
FirebaseOptions.Builder builder = new FirebaseOptions.Builder() .setApplicationId("1:0123456789012:android:0123456789abcdef") .setApiKey("your_api_key") .setDatabaseUrl("https://your-app.firebaseio.com") .setStorageBucket("your-app.appspot.com"); FirebaseApp.initializeApp(this, builder.build());
Since expanding Firebase to become Google's mobile application development platform at Google I/O last year, our amazing community of developers has created over 1 million Firebase projects.
We're thrilled so many of you use and trust us. While Firebase is a full suite of products for building and growing apps, we know that some apps need more than we offer out-of-the-box. That's why we're bringing Firebase much closer to Google Cloud Platform (GCP) to serve even the most demanding applications, whether you're a new startup or a large enterprise.
Firebase already shares the same account and billing system as GCP, so you can attach Firebase services to your GCP project and vice-versa. This makes for powerful combinations, such as exporting raw event data from Firebase Analytics into BigQuery for ad-hoc analysis. Starting today, we're beginning to share products too.
First, Firebase developers have been asking for ways to extend their app's functionality without spinning up a server, and Cloud Functions for Firebase lets you do just that. Cloud Functions is our new event-driven serverless compute offering that enters public beta today. The infrastructure is shared between Cloud and Firebase, allowing you to invoke a function or access resources from throughout the Cloud/Firebase ecosystem. For more information, read the announcement on the Firebase blog and Cloud blog.
Next, we're bringing Firebase Storage closer to Cloud Storage. Firebase Storage launched 10 months ago, and lets you easily upload and download files from your device directly to Cloud Storage. Previously we gave you a single bucket for your files. Now we're fully aligning the two products and letting you use any Cloud Storage bucket, from any global region and from any storage class, all straight from the Firebase SDK. To reflect this alignment we're renaming the product Cloud Storage for Firebase. Read more in our blog post.
Stay tuned for more product integrations in the future as Firebase continues to provide direct client-side access to GCP infrastructure through our iOS, Web, and Android SDKs.
We love lawyers almost as much as developers, so we're extending GCP's Terms of Service to cover several Firebase products. This makes Firebase and Cloud simpler to evaluate and use together. Products to be covered include: Authentication, Hosting, Storage, Functions, and Test Lab. Our streamlined Terms of Service will take effect soon.
Firebase brings together the best of Google on mobile -- whether that's Google's flagship advertising solutions like AdMob and AdWords, or Google's analytics expertise in the form of Firebase Analytics.
Google Cloud Platform lets you to benefit from the institutional knowledge Google has developed from almost two decades of running global-scale computing infrastructure.
By bringing together the ease-of-use of Firebase with the full-range of GCP infrastructure offerings, we're better able to serve you up and down the stack. If you're a startup using Firebase to quickly get to market, you can now easily scale into a full public cloud. If you're an existing business running on GCP who wants to ship a mobile app, we've got you covered too.
We can't wait to see what you build with Firebase and Google Cloud Platform!
func recordGameOver() { let tracker = GAI.sharedInstance().defaultTracker let gameOverEvent = GAIDictionaryBuilder.createEvent(withCategory: "gameOver", action: "totalScore", label: "", value: myGameStats.totalScore as NSNumber) let enemiesBeatenEvent = GAIDictionaryBuilder.createEvent(withCategory: "gameOver", action: "enemiesBeaten", label: "", value: myGameStats.enemiesBeaten as NSNumber) let roundsSurvivedEvent = GAIDictionaryBuilder.createEvent(withCategory: "gameOver", action: "roundsSurvived", label: "", value: myGameStats.roundsSurvived as NSNumber) tracker?.send(gameOverEvent.build() as [NSObject: AnyObject]) tracker?.send(enemiesBeatenEvent.build() as [NSObject: AnyObject]) tracker?.send(roundsSurvivedEvent.build() as [NSObject: AnyObject]) }
FIRAnalytics.logEvent(withName: "gameOverTotalScore", parameters: [kFIRParameterValue: myGameStats.totalScore as NSObject]) FIRAnalytics.logEvent(withName: "gameOverEnemiesBeaten", parameters: [kFIRParameterValue: myGameStats.totalScore as NSObject]) FIRAnalytics.logEvent(withName: "gameOverTotalScore", parameters: [kFIRParameterValue: myGameStats.totalScore as NSObject])
let finalStats = ["totalScore": myGameStats.totalScore as NSObject, "enemiesBeaten": myGameStats.enemiesBeaten as NSObject, "roundsSurvived": myGameStats.roundsSurvived as NSObject] FIRAnalytics.logEvent(withName: "gameOver", parameters: finalStats)
GoogleService-info.plist
GoogleService-info
TRACKING_ID
func recordGameOver() { // All the old code you had previously to record Google Analytics // … // … So much code … // … // Now add the Firebase stuff let finalStats = ["totalScore": myGameStats.totalScore as NSObject, "enemiesBeaten": myGameStats.enemiesBeaten as NSObject, "roundsSurvived": myGameStats.roundsSurvived as NSObject] FIRAnalytics.logEvent(withName: "gameOver", parameters: finalStats) }
func recordGameOver() { let finalStats = ["totalScore": myGameStats.totalScore as NSObject, "enemiesBeaten": myGameStats.enemiesBeaten as NSObject, "roundsSurvived": myGameStats.roundsSurvived as NSObject] FIRAnalytics.logEvent(withName: "gameOver", parameters: finalStats) // That's it! }
SELECT AVG(hit.eventInfo.eventValue) FROM `my_awesome_app.ga_sessions_20170123`, UNNEST(hits) AS hit WHERE hit.eventInfo.eventCategory = "gameOver" AND hit.eventInfo.eventAction = "totalScore"
SELECT COUNT(*), AVG(total_score) AS average FROM ( SELECT event_param.value.int_value AS total_score FROM `firebase-project.com_example_awesome_app.app_events_20170123`, UNNEST(event_dim) AS event, UNNEST(event.params) AS event_param WHERE event.name = "gameOver" AND event_param.key = "totalScore" UNION ALL SELECT hit.eventInfo.eventValue AS total_score FROM `my_awesome_app.ga_sessions_20170123`, UNNEST(hits) AS hit WHERE hit.eventInfo.eventCategory = "gameOver" AND hit.eventInfo.eventAction = "totalScore" )