Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updated firebase-event-proxy sample code to latest Firebase SDK #244

Merged
merged 5 commits into from
May 26, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions appengine/firebase-event-proxy/gae-firebase-event-proxy/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -55,19 +55,19 @@
<version>1.2</version>
</dependency>
<dependency>
<groupId>com.firebase</groupId>
<artifactId>firebase-client-jvm</artifactId>
<version>[1.0.8,)</version>
<groupId>com.google.firebase</groupId>
<artifactId>firebase-server-sdk</artifactId>
<version>[3.0.0,)</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.7.3</version>
</dependency>
<dependency>
<groupId>com.firebase</groupId>
<artifactId>firebase-token-generator</artifactId>
<version>2.0.0</version>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.5.3</version>
</dependency>

<!-- Test Dependencies -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,52 +18,49 @@

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;
import com.google.firebase.FirebaseApp;
import com.google.firebase.FirebaseOptions;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;

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;

public class FirebaseEventProxy {

private static final Logger log = Logger.getLogger(FirebaseEventProxy.class.getName());

private String firebaseAuthToken;

public FirebaseEventProxy() {
// Store Firebase authentication token as an instance variable.
this.firebaseAuthToken = this.getFirebaseAuthToken(this.getFirebaseSecret());
String firebaseLocation = "https://crackling-torch-392.firebaseio.com";
Map<String, Object> databaseAuthVariableOverride = new HashMap<String, Object>();
// uid and provider will have to match what you have in your firebase security rules
databaseAuthVariableOverride.put("uid", "gae-firebase-event-proxy");
databaseAuthVariableOverride.put("provider", "com.example");
try {
FirebaseOptions options = new FirebaseOptions.Builder()
.setServiceAccount(new FileInputStream("gae-firebase-secrets.json"))
.setDatabaseUrl(firebaseLocation)
.setDatabaseAuthVariableOverride(databaseAuthVariableOverride).build();
FirebaseApp.initializeApp(options);
} catch (IOException e) {
throw new RuntimeException(
"Error reading firebase secrets from file: src/main/webapp/gae-firebase-secrets.json: "
+ e.getMessage());
}
}

public void start() {
String firebaseLocation = "https://gae-fb-proxy.firebaseio.com/";
Firebase firebase = new Firebase(firebaseLocation);

// 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");
}
});
DatabaseReference firebase = FirebaseDatabase.getInstance().getReference();

// Subscribe to value events. Depending on use case, you may want to subscribe to child events
// through childEventListener.
Expand All @@ -73,7 +70,7 @@ public void onDataChange(DataSnapshot snapshot) {
if (snapshot.exists()) {
try {
// Convert value to JSON using Jackson
String json = new ObjectMapper().writeValueAsString(snapshot.getValue());
String json = new ObjectMapper().writeValueAsString(snapshot.getValue(false));

// Replace the URL with the url of your own listener app.
URL dest = new URL("http://gae-firebase-listener-python.appspot.com/log");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok for now, but it's not a good thing to ask users to change lines deep in the middle of the code. My preferred place for GAE is to set it in the pom, so it can be overridden in the mvn command line -Dpyurl=... you could then update a properties file from mvn, using substitution ${pyurl} and read it in the code from the properties file. If not that, then just set it as a constant early in the source file.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that what you suggest is better style. However this code will be used in an article as sample code and I think it is better to use code that directly calls Firebase API directly even though that hurts encapsulation. I think directly calling the API makes it easier for customers to understand the Firebase API because there are fewer things for them to be thinking about.

An early draft of the article is here:
https://docs.google.com/document/d/1H_W9C8cO_laKYElzbBBgIv9ECMBA3LRJqEebqfquWAI/edit#

Expand Down Expand Up @@ -109,36 +106,9 @@ public void onDataChange(DataSnapshot snapshot) {
}

@Override
public void onCancelled(FirebaseError error) {
public void onCancelled(DatabaseError 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<String, Object> authPayload = new HashMap<String, Object>();
// 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);
}
}