From 3e6ef908d1e40d86d59553134c400667f81e8a20 Mon Sep 17 00:00:00 2001 From: misterwilliam Date: Wed, 11 May 2016 14:13:16 -0700 Subject: [PATCH 1/3] initial commit of Firebase Event Proxy --- appengine/firebase-event-proxy/README.md | 49 ++++++ .../gae-firebase-event-proxy/pom.xml | 144 ++++++++++++++++++ .../FirebaseEventProxy.java | 123 +++++++++++++++ .../ServletContextListenerImpl.java | 23 +++ .../src/main/webapp/WEB-INF/appengine-web.xml | 14 ++ .../main/webapp/WEB-INF/logging.properties | 13 ++ .../src/main/webapp/WEB-INF/web.xml | 13 ++ .../src/main/webapp/index.jsp | 12 ++ .../gae-firebase-listener-python/.gitignore | 1 + .../gae-firebase-listener-python/app.yaml | 7 + .../gae-firebase-listener-python/main.py | 24 +++ 11 files changed, 423 insertions(+) create mode 100644 appengine/firebase-event-proxy/README.md create mode 100644 appengine/firebase-event-proxy/gae-firebase-event-proxy/pom.xml create mode 100644 appengine/firebase-event-proxy/gae-firebase-event-proxy/src/main/java/com/example/GaeFirebaseEventProxy/FirebaseEventProxy.java create mode 100644 appengine/firebase-event-proxy/gae-firebase-event-proxy/src/main/java/com/example/GaeFirebaseEventProxy/ServletContextListenerImpl.java create mode 100644 appengine/firebase-event-proxy/gae-firebase-event-proxy/src/main/webapp/WEB-INF/appengine-web.xml create mode 100644 appengine/firebase-event-proxy/gae-firebase-event-proxy/src/main/webapp/WEB-INF/logging.properties create mode 100644 appengine/firebase-event-proxy/gae-firebase-event-proxy/src/main/webapp/WEB-INF/web.xml create mode 100644 appengine/firebase-event-proxy/gae-firebase-event-proxy/src/main/webapp/index.jsp create mode 100644 appengine/firebase-event-proxy/gae-firebase-listener-python/.gitignore create mode 100644 appengine/firebase-event-proxy/gae-firebase-listener-python/app.yaml create mode 100644 appengine/firebase-event-proxy/gae-firebase-listener-python/main.py diff --git a/appengine/firebase-event-proxy/README.md b/appengine/firebase-event-proxy/README.md new file mode 100644 index 00000000000..eeb8b4ac107 --- /dev/null +++ b/appengine/firebase-event-proxy/README.md @@ -0,0 +1,49 @@ +# App Engine Firebase Event Proxy + +An example app that illustrates how to create a Java App Engine Standard Environment +app that proxies Firebase events to another App Engine app. + +# Java Firebase Event Proxy +Illustrates how to authenticate and subscribe to Firebase from Java App Engine. + +# Python App Engine Listener +Illustrates how to authenticate messages received from the proxy app. + +## Setup + +### Java Firebase Event Proxy +Firebase Secret +Put your Firebase secret in the file: +gae-firebase-event-proxy/src/main/webapp/firebase-secret.properties +``` +firebaseSecret= +``` + +* Billing must be enabled from Cloud console. +* Manual scaling should turned on and configured to 1 instance in appengine-web.xml + +## Running locally +### Java Firebase Event Proxy +``` +cd gae-firebase-event-proxy +mvn appengine:devserver +``` + +### Python App Engine Listener +``` +cd gae-firebase-listener-python +dev_appserver . +``` + +## Deploying + +### Java Firebase Event Proxy +``` +cd gae-firebase-event-proxy +mvn appengine:upload +``` + +### Python App Engine Listener +``` +appcfg.py -A -V v1 update gae-firebase-listener-python +``` diff --git a/appengine/firebase-event-proxy/gae-firebase-event-proxy/pom.xml b/appengine/firebase-event-proxy/gae-firebase-event-proxy/pom.xml new file mode 100644 index 00000000000..199a6ebc1a5 --- /dev/null +++ b/appengine/firebase-event-proxy/gae-firebase-event-proxy/pom.xml @@ -0,0 +1,144 @@ + + + + 4.0.0 + war + 1.0-SNAPSHOT + + com.example.GaeFirebaseEventProxy + GaeFirebaseEventProxy + + + gae-firebase-event-proxy + 1 + 1.9.36 + 2.0.9.74.v20150814 + UTF-8 + true + + + + 3.1.0 + + + + + + com.google.appengine + appengine-api-1.0-sdk + ${appengine.version} + + + javax.servlet + servlet-api + 2.5 + provided + + + jstl + jstl + 1.2 + + + com.firebase + firebase-client-jvm + [1.0.8,) + + + com.fasterxml.jackson.core + jackson-core + 2.7.3 + + + com.firebase + firebase-token-generator + 2.0.0 + + + + + com.google.appengine + appengine-testing + ${appengine.version} + test + + + com.google.appengine + appengine-api-stubs + ${appengine.version} + test + + + + + + ${project.build.directory}/${project.build.finalName}/WEB-INF/classes + + + org.codehaus.mojo + versions-maven-plugin + 2.1 + + + compile + + display-dependency-updates + display-plugin-updates + + + + + + org.apache.maven.plugins + 3.1 + maven-compiler-plugin + + 1.7 + 1.7 + + + + org.apache.maven.plugins + maven-war-plugin + 2.4 + + true + + + + ${basedir}/src/main/webapp/WEB-INF + true + WEB-INF + + + + + + + com.google.appengine + appengine-maven-plugin + ${appengine.version} + + false + ${app.version} + + + + + + + + com.google.appengine + gcloud-maven-plugin + ${gcloud.plugin.version} + + true + + + + + diff --git a/appengine/firebase-event-proxy/gae-firebase-event-proxy/src/main/java/com/example/GaeFirebaseEventProxy/FirebaseEventProxy.java b/appengine/firebase-event-proxy/gae-firebase-event-proxy/src/main/java/com/example/GaeFirebaseEventProxy/FirebaseEventProxy.java new file mode 100644 index 00000000000..4d3206e342c --- /dev/null +++ b/appengine/firebase-event-proxy/gae-firebase-event-proxy/src/main/java/com/example/GaeFirebaseEventProxy/FirebaseEventProxy.java @@ -0,0 +1,123 @@ +package com.example.GaeFirebaseEventProxy; + +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLEncoder; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; +import java.util.logging.Logger; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.firebase.client.AuthData; +import com.firebase.client.DataSnapshot; +import com.firebase.client.Firebase; +import com.firebase.client.FirebaseError; +import com.firebase.client.ValueEventListener; +import com.firebase.security.token.TokenGenerator; +import com.google.appengine.api.utils.SystemProperty; + +public class FirebaseEventProxy { + + private static final Logger log = Logger.getLogger(FirebaseEventProxy.class.getName()); + + private String firebaseAuthToken; + + public FirebaseEventProxy() { + this.firebaseAuthToken = this.getFirebaseAuthToken(this.getFirebaseSecret()); + } + + public void start() { + String FIREBASE_LOCATION = "https://gae-fb-proxy.firebaseio.com/"; + Firebase firebase = new Firebase(FIREBASE_LOCATION); + // Authenticate with Firebase + firebase.authWithCustomToken(this.firebaseAuthToken, new Firebase.AuthResultHandler() { + @Override + public void onAuthenticationError(FirebaseError error) { + log.severe("Firebase login error: " + error.getMessage()); + } + + @Override + public void onAuthenticated(AuthData auth) { + log.info("Firebase login successful"); + } + }); + + // Subscribe to value events. Depending on use case, you may want to subscribe to child events + // through childEventListener. + firebase.addValueEventListener(new ValueEventListener() { + @Override + public void onDataChange(DataSnapshot snapshot) { + if (snapshot.exists()) { + try { + // Convert value to JSON using Jackson + String json = new ObjectMapper().writeValueAsString(snapshot.getValue()); + // Replace the URL with the url of your own listener app. + URL dest = new URL("http://gae-firebase-listener-python.appspot.com/log"); + HttpURLConnection connection = (HttpURLConnection) dest.openConnection(); + connection.setRequestMethod("POST"); + connection.setDoOutput(true); + // Rely on X-Appengine-Inbound-Appid to authenticate. Turning off redirects is + // required to enable. + connection.setInstanceFollowRedirects(false); + // Fill out header if in dev environment + if (SystemProperty.environment.value() != SystemProperty.Environment.Value.Production) { + connection.setRequestProperty("X-Appengine-Inbound-Appid", "dev-instance"); + } + // Put Firebase data into http request + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.append("&fbSnapshot="); + stringBuilder.append(URLEncoder.encode(json, "UTF-8")); + connection.getOutputStream().write(stringBuilder.toString().getBytes()); + if (connection.getResponseCode() != 200) { + log.severe("Forwarding failed"); + } else { + log.info("Sent: " + json); + } + } catch (JsonProcessingException e) { + log.severe("Unable to convert Firebase response to JSON: " + e.getMessage()); + } catch (IOException e) { + log.severe("Error in connecting to app engine: " + e.getMessage()); + } + } + } + + @Override + public void onCancelled(FirebaseError error) { + log.severe("Firebase connection cancelled: " + error.getMessage()); + } + }); + } + + private String getFirebaseSecret() { + Properties props = new Properties(); + try { + // Read from src/main/webapp/firebase-secrets.properties + InputStream inputStream = new FileInputStream("firebase-secret.properties"); + props.load(inputStream); + return props.getProperty("firebaseSecret"); + } catch (java.net.MalformedURLException e) { + throw new RuntimeException( + "Error reading firebase secrets from file: src/main/webapp/firebase-sercrets.properties: " + + e.getMessage()); + } catch (IOException e) { + throw new RuntimeException( + "Error reading firebase secrets from file: src/main/webapp/firebase-sercrets.properties: " + + e.getMessage()); + } + } + + private String getFirebaseAuthToken(String firebaseSecret) { + Map authPayload = new HashMap(); + // uid and provider will have to match what you have in your firebase security rules + authPayload.put("uid", "gae-firebase-event-proxy"); + authPayload.put("provider", "com.example"); + TokenGenerator tokenGenerator = new TokenGenerator(firebaseSecret); + return tokenGenerator.createToken(authPayload); + } + +} diff --git a/appengine/firebase-event-proxy/gae-firebase-event-proxy/src/main/java/com/example/GaeFirebaseEventProxy/ServletContextListenerImpl.java b/appengine/firebase-event-proxy/gae-firebase-event-proxy/src/main/java/com/example/GaeFirebaseEventProxy/ServletContextListenerImpl.java new file mode 100644 index 00000000000..06000b1a572 --- /dev/null +++ b/appengine/firebase-event-proxy/gae-firebase-event-proxy/src/main/java/com/example/GaeFirebaseEventProxy/ServletContextListenerImpl.java @@ -0,0 +1,23 @@ +package com.example.GaeFirebaseEventProxy; + +import java.util.logging.Logger; + +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; + +public class ServletContextListenerImpl implements ServletContextListener { + + private static final Logger log = Logger.getLogger(ServletContextListener.class.getName()); + + @Override + public void contextInitialized(ServletContextEvent event) { + log.info("Starting ...."); + FirebaseEventProxy proxy = new FirebaseEventProxy(); + proxy.start(); + } + + @Override + public void contextDestroyed(ServletContextEvent event) { + // App Engine does not currently invoke this method. + } +} diff --git a/appengine/firebase-event-proxy/gae-firebase-event-proxy/src/main/webapp/WEB-INF/appengine-web.xml b/appengine/firebase-event-proxy/gae-firebase-event-proxy/src/main/webapp/WEB-INF/appengine-web.xml new file mode 100644 index 00000000000..c9c4368aad9 --- /dev/null +++ b/appengine/firebase-event-proxy/gae-firebase-event-proxy/src/main/webapp/WEB-INF/appengine-web.xml @@ -0,0 +1,14 @@ + + + ${app.id} + ${app.version} + true + + + 1 + + + + + + diff --git a/appengine/firebase-event-proxy/gae-firebase-event-proxy/src/main/webapp/WEB-INF/logging.properties b/appengine/firebase-event-proxy/gae-firebase-event-proxy/src/main/webapp/WEB-INF/logging.properties new file mode 100644 index 00000000000..19e9bf064c1 --- /dev/null +++ b/appengine/firebase-event-proxy/gae-firebase-event-proxy/src/main/webapp/WEB-INF/logging.properties @@ -0,0 +1,13 @@ +# A default java.util.logging configuration. +# (All App Engine logging is through java.util.logging by default). +# +# To use this configuration, copy it into your application's WEB-INF +# folder and add the following to your appengine-web.xml: +# +# +# +# +# + +# Set the default logging level for all loggers to WARNING +.level = INFO diff --git a/appengine/firebase-event-proxy/gae-firebase-event-proxy/src/main/webapp/WEB-INF/web.xml b/appengine/firebase-event-proxy/gae-firebase-event-proxy/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 00000000000..eff45fff539 --- /dev/null +++ b/appengine/firebase-event-proxy/gae-firebase-event-proxy/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,13 @@ + + + + + com.example.GaeFirebaseEventProxy.ServletContextListenerImpl + + + index.jsp + + diff --git a/appengine/firebase-event-proxy/gae-firebase-event-proxy/src/main/webapp/index.jsp b/appengine/firebase-event-proxy/gae-firebase-event-proxy/src/main/webapp/index.jsp new file mode 100644 index 00000000000..5181a70d010 --- /dev/null +++ b/appengine/firebase-event-proxy/gae-firebase-event-proxy/src/main/webapp/index.jsp @@ -0,0 +1,12 @@ +<%@ page contentType="text/html;charset=UTF-8" language="java" %> + + + + + + + +

Status: up

+ + + diff --git a/appengine/firebase-event-proxy/gae-firebase-listener-python/.gitignore b/appengine/firebase-event-proxy/gae-firebase-listener-python/.gitignore new file mode 100644 index 00000000000..0d20b6487c6 --- /dev/null +++ b/appengine/firebase-event-proxy/gae-firebase-listener-python/.gitignore @@ -0,0 +1 @@ +*.pyc diff --git a/appengine/firebase-event-proxy/gae-firebase-listener-python/app.yaml b/appengine/firebase-event-proxy/gae-firebase-listener-python/app.yaml new file mode 100644 index 00000000000..f041d384c05 --- /dev/null +++ b/appengine/firebase-event-proxy/gae-firebase-listener-python/app.yaml @@ -0,0 +1,7 @@ +runtime: python27 +api_version: 1 +threadsafe: true + +handlers: +- url: /.* + script: main.app diff --git a/appengine/firebase-event-proxy/gae-firebase-listener-python/main.py b/appengine/firebase-event-proxy/gae-firebase-listener-python/main.py new file mode 100644 index 00000000000..72c5c94a979 --- /dev/null +++ b/appengine/firebase-event-proxy/gae-firebase-listener-python/main.py @@ -0,0 +1,24 @@ +import os +import webapp2 + +IS_DEV = os.environ["SERVER_SOFTWARE"][:3] == "Dev" +allowed_users = set() +if IS_DEV: + allowed_users.add("dev-instance") +else: + # Add your Java App Engine proxy App Id here + allowed_users.add("your-java-appengine-proxy-app-id") + +class LoggingHandler(webapp2.RequestHandler): + + def post(self): + user = self.request.headers.get('X-Appengine-Inbound-Appid', None) + if user and user in allowed_users: + firebaseSnapshot = self.request.params['fbSnapshot'] + print firebaseSnapshot + else: + print "Got unauthenticated user: %s" % user + +app = webapp2.WSGIApplication([ + webapp2.Route('/log', LoggingHandler), +]) From e76c6079992b2adaeb8058bd379fb6dbfa4292af Mon Sep 17 00:00:00 2001 From: misterwilliam Date: Wed, 11 May 2016 14:19:32 -0700 Subject: [PATCH 2/3] Add licenses at the beginning of all files --- .../gae-firebase-event-proxy/pom.xml | 12 ++++++++++++ .../ServletContextListenerImpl.java | 16 ++++++++++++++++ .../src/main/webapp/WEB-INF/appengine-web.xml | 17 +++++++++++++++-- .../src/main/webapp/WEB-INF/logging.properties | 16 +++++++++++++++- .../src/main/webapp/WEB-INF/web.xml | 13 +++++++++++++ .../src/main/webapp/index.jsp | 13 +++++++++++++ .../gae-firebase-listener-python/main.py | 14 ++++++++++++++ 7 files changed, 98 insertions(+), 3 deletions(-) diff --git a/appengine/firebase-event-proxy/gae-firebase-event-proxy/pom.xml b/appengine/firebase-event-proxy/gae-firebase-event-proxy/pom.xml index 199a6ebc1a5..c4975f1f095 100644 --- a/appengine/firebase-event-proxy/gae-firebase-event-proxy/pom.xml +++ b/appengine/firebase-event-proxy/gae-firebase-event-proxy/pom.xml @@ -1,3 +1,15 @@ + diff --git a/appengine/firebase-event-proxy/gae-firebase-event-proxy/src/main/java/com/example/GaeFirebaseEventProxy/ServletContextListenerImpl.java b/appengine/firebase-event-proxy/gae-firebase-event-proxy/src/main/java/com/example/GaeFirebaseEventProxy/ServletContextListenerImpl.java index 06000b1a572..c096d0f215d 100644 --- a/appengine/firebase-event-proxy/gae-firebase-event-proxy/src/main/java/com/example/GaeFirebaseEventProxy/ServletContextListenerImpl.java +++ b/appengine/firebase-event-proxy/gae-firebase-event-proxy/src/main/java/com/example/GaeFirebaseEventProxy/ServletContextListenerImpl.java @@ -1,3 +1,19 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.example.GaeFirebaseEventProxy; import java.util.logging.Logger; diff --git a/appengine/firebase-event-proxy/gae-firebase-event-proxy/src/main/webapp/WEB-INF/appengine-web.xml b/appengine/firebase-event-proxy/gae-firebase-event-proxy/src/main/webapp/WEB-INF/appengine-web.xml index c9c4368aad9..96aaab69ef4 100644 --- a/appengine/firebase-event-proxy/gae-firebase-event-proxy/src/main/webapp/WEB-INF/appengine-web.xml +++ b/appengine/firebase-event-proxy/gae-firebase-event-proxy/src/main/webapp/WEB-INF/appengine-web.xml @@ -1,13 +1,26 @@ + + ${app.id} ${app.version} true - + 1 - + diff --git a/appengine/firebase-event-proxy/gae-firebase-event-proxy/src/main/webapp/WEB-INF/logging.properties b/appengine/firebase-event-proxy/gae-firebase-event-proxy/src/main/webapp/WEB-INF/logging.properties index 19e9bf064c1..e325f6cb079 100644 --- a/appengine/firebase-event-proxy/gae-firebase-event-proxy/src/main/webapp/WEB-INF/logging.properties +++ b/appengine/firebase-event-proxy/gae-firebase-event-proxy/src/main/webapp/WEB-INF/logging.properties @@ -1,9 +1,23 @@ +# Copyright 2016 Google Inc. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + # A default java.util.logging configuration. # (All App Engine logging is through java.util.logging by default). # # To use this configuration, copy it into your application's WEB-INF # folder and add the following to your appengine-web.xml: -# +# # # # diff --git a/appengine/firebase-event-proxy/gae-firebase-event-proxy/src/main/webapp/WEB-INF/web.xml b/appengine/firebase-event-proxy/gae-firebase-event-proxy/src/main/webapp/WEB-INF/web.xml index eff45fff539..b8ded3bcce1 100644 --- a/appengine/firebase-event-proxy/gae-firebase-event-proxy/src/main/webapp/WEB-INF/web.xml +++ b/appengine/firebase-event-proxy/gae-firebase-event-proxy/src/main/webapp/WEB-INF/web.xml @@ -1,3 +1,16 @@ + + + <%@ page contentType="text/html;charset=UTF-8" language="java" %> diff --git a/appengine/firebase-event-proxy/gae-firebase-listener-python/main.py b/appengine/firebase-event-proxy/gae-firebase-listener-python/main.py index 72c5c94a979..49145bbd749 100644 --- a/appengine/firebase-event-proxy/gae-firebase-listener-python/main.py +++ b/appengine/firebase-event-proxy/gae-firebase-listener-python/main.py @@ -1,3 +1,17 @@ +# Copyright 2016 Google Inc. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + import os import webapp2 From 67de559fab53022efca5126714d4bb73dee16719 Mon Sep 17 00:00:00 2001 From: misterwilliam Date: Wed, 11 May 2016 14:31:47 -0700 Subject: [PATCH 3/3] Add whitespace and more comments --- .../FirebaseEventProxy.java | 23 ++++++++++++++++++- .../ServletContextListenerImpl.java | 1 + 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/appengine/firebase-event-proxy/gae-firebase-event-proxy/src/main/java/com/example/GaeFirebaseEventProxy/FirebaseEventProxy.java b/appengine/firebase-event-proxy/gae-firebase-event-proxy/src/main/java/com/example/GaeFirebaseEventProxy/FirebaseEventProxy.java index 4d3206e342c..ffff83eaa34 100644 --- a/appengine/firebase-event-proxy/gae-firebase-event-proxy/src/main/java/com/example/GaeFirebaseEventProxy/FirebaseEventProxy.java +++ b/appengine/firebase-event-proxy/gae-firebase-event-proxy/src/main/java/com/example/GaeFirebaseEventProxy/FirebaseEventProxy.java @@ -1,3 +1,19 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.example.GaeFirebaseEventProxy; import java.io.FileInputStream; @@ -28,12 +44,14 @@ public class FirebaseEventProxy { private String firebaseAuthToken; public FirebaseEventProxy() { + // Store Firebase authentication token as an instance variable. this.firebaseAuthToken = this.getFirebaseAuthToken(this.getFirebaseSecret()); } public void start() { String FIREBASE_LOCATION = "https://gae-fb-proxy.firebaseio.com/"; Firebase firebase = new Firebase(FIREBASE_LOCATION); + // Authenticate with Firebase firebase.authWithCustomToken(this.firebaseAuthToken, new Firebase.AuthResultHandler() { @Override @@ -56,18 +74,22 @@ public void onDataChange(DataSnapshot snapshot) { try { // Convert value to JSON using Jackson String json = new ObjectMapper().writeValueAsString(snapshot.getValue()); + // Replace the URL with the url of your own listener app. URL dest = new URL("http://gae-firebase-listener-python.appspot.com/log"); HttpURLConnection connection = (HttpURLConnection) dest.openConnection(); connection.setRequestMethod("POST"); connection.setDoOutput(true); + // Rely on X-Appengine-Inbound-Appid to authenticate. Turning off redirects is // required to enable. connection.setInstanceFollowRedirects(false); + // Fill out header if in dev environment if (SystemProperty.environment.value() != SystemProperty.Environment.Value.Production) { connection.setRequestProperty("X-Appengine-Inbound-Appid", "dev-instance"); } + // Put Firebase data into http request StringBuilder stringBuilder = new StringBuilder(); stringBuilder.append("&fbSnapshot="); @@ -119,5 +141,4 @@ private String getFirebaseAuthToken(String firebaseSecret) { TokenGenerator tokenGenerator = new TokenGenerator(firebaseSecret); return tokenGenerator.createToken(authPayload); } - } diff --git a/appengine/firebase-event-proxy/gae-firebase-event-proxy/src/main/java/com/example/GaeFirebaseEventProxy/ServletContextListenerImpl.java b/appengine/firebase-event-proxy/gae-firebase-event-proxy/src/main/java/com/example/GaeFirebaseEventProxy/ServletContextListenerImpl.java index c096d0f215d..b50dc4d3961 100644 --- a/appengine/firebase-event-proxy/gae-firebase-event-proxy/src/main/java/com/example/GaeFirebaseEventProxy/ServletContextListenerImpl.java +++ b/appengine/firebase-event-proxy/gae-firebase-event-proxy/src/main/java/com/example/GaeFirebaseEventProxy/ServletContextListenerImpl.java @@ -21,6 +21,7 @@ import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; +// ServletContextListener that is called whenever your App Engine app starts up. public class ServletContextListenerImpl implements ServletContextListener { private static final Logger log = Logger.getLogger(ServletContextListener.class.getName());