diff --git a/LectureExamples/FirebaseDemo/.gitignore b/LectureExamples/FirebaseDemo/.gitignore index 39fb081a42a86ccf8f9cf99dbccc8bdf7c828bce..699660215a09e76b438d820480e1983c55c560ee 100644 --- a/LectureExamples/FirebaseDemo/.gitignore +++ b/LectureExamples/FirebaseDemo/.gitignore @@ -7,3 +7,4 @@ /build /captures .externalNativeBuild +backend/src/main/webapp/WEB-INF/*.json diff --git a/LectureExamples/FirebaseDemo/app/src/main/AndroidManifest.xml b/LectureExamples/FirebaseDemo/app/src/main/AndroidManifest.xml index 0aa43383d56fb40075205eea4ffca3a08f4d5eb3..c8fdf3c4074fcc5f7439d64746738ed908378207 100644 --- a/LectureExamples/FirebaseDemo/app/src/main/AndroidManifest.xml +++ b/LectureExamples/FirebaseDemo/app/src/main/AndroidManifest.xml @@ -2,6 +2,8 @@ <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.andrejrasevic.firebasedemo"> + <uses-permission android:name="android.permission.INTERNET" /> + <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" diff --git a/LectureExamples/FirebaseDemo/backend/build.gradle b/LectureExamples/FirebaseDemo/backend/build.gradle new file mode 100644 index 0000000000000000000000000000000000000000..46fffdfc56a6a2be93f37cb2a8cebe087f11471e --- /dev/null +++ b/LectureExamples/FirebaseDemo/backend/build.gradle @@ -0,0 +1,37 @@ +// If you would like more information on the gradle-appengine-plugin please refer to the github page +// https://github.com/GoogleCloudPlatform/gradle-appengine-plugin + +buildscript { + repositories { + jcenter() + } + dependencies { + classpath 'com.google.appengine:gradle-appengine-plugin:1.9.42' + } +} + +repositories { + jcenter(); +} + +apply plugin: 'java' +apply plugin: 'war' +apply plugin: 'appengine' + +sourceCompatibility = JavaVersion.VERSION_1_7 +targetCompatibility = JavaVersion.VERSION_1_7 + +dependencies { + appengineSdk 'com.google.appengine:appengine-java-sdk:1.9.42' + compile 'javax.servlet:servlet-api:2.5' + compile 'com.google.appengine:appengine-api-1.0-sdk:1.9.58' + compile 'com.google.firebase:firebase-server-sdk:3.0.3' + compile 'org.apache.httpcomponents:httpclient:4.5.3' +} + +appengine { + downloadSdk = true + appcfg { + oauth2 = true + } +} diff --git a/LectureExamples/FirebaseDemo/backend/src/main/java/com/example/andrej/rasevic/myapplication/backend/MyServlet.java b/LectureExamples/FirebaseDemo/backend/src/main/java/com/example/andrej/rasevic/myapplication/backend/MyServlet.java new file mode 100644 index 0000000000000000000000000000000000000000..fabc948453824b96cc259863e86f8e1f4583d629 --- /dev/null +++ b/LectureExamples/FirebaseDemo/backend/src/main/java/com/example/andrej/rasevic/myapplication/backend/MyServlet.java @@ -0,0 +1,129 @@ +package com.example.andrej.rasevic.myapplication.backend; + + import com.google.api.client.googleapis.auth.clientlogin.ClientLogin; + 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.UnsupportedEncodingException; + import java.util.Iterator; + import java.util.Properties; + import java.util.logging.Logger; + + import javax.mail.Message; + import javax.mail.MessagingException; + import javax.mail.Session; + import javax.mail.Transport; + import javax.mail.internet.InternetAddress; + import javax.mail.internet.MimeMessage; + import javax.servlet.http.*; + import javax.xml.ws.Response; + +public class MyServlet extends HttpServlet { + static Logger Log = Logger.getLogger("com.example.andrej.rasevic.myapplication.backend.MyServlet"); + + @Override + public void doGet(HttpServletRequest req, HttpServletResponse resp) + throws IOException { + Log.info("Sending the todo list email."); + + String outString; + outString = "<p>Sending the todo list email.</p><p><strong>Note:</strong> "; + outString = outString.concat("the servlet must be deployed to App Engine in order to "); + outString = outString.concat("send the email. Running the server locally writes a message "); + outString = outString.concat("to the log file instead of sending an email message.</p>"); + + resp.getWriter().println(outString); + + // Note: Ensure that the [PRIVATE_KEY_FILENAME].json has read + // permissions set. + FirebaseOptions options = new FirebaseOptions.Builder() + .setServiceAccount(getServletContext().getResourceAsStream("/WEB-INF/FirebaseDemo-a6320e903952.json")) + .setDatabaseUrl("https://fir-demo-d5acb.firebaseio.com/") + .build(); + + try { + FirebaseApp.getInstance(); + Log.info("Got to here!"); + } + catch (Exception error){ + Log.info("doesn't exist..."); + } + + try { + FirebaseApp.initializeApp(options); + Log.info("now I got to here!!"); + } + catch(Exception error){ + Log.info("already exists..."); + } + + // As an admin, the app has access to read and write all data, regardless of Security Rules + DatabaseReference ref = FirebaseDatabase + .getInstance() + .getReference("todoItems"); + + // This fires when the servlet first runs, returning all the existing values + // only runs once, until the servlet starts up again. + ref.addListenerForSingleValueEvent(new ValueEventListener() { + + @Override + public void onDataChange(DataSnapshot dataSnapshot) { + Object document = dataSnapshot.getValue(); + Log.info("new value: "+ document); + + String todoText = "Don't forget to...\n\n"; + + Iterator<DataSnapshot> children = dataSnapshot.getChildren().iterator(); + + while(children.hasNext()){ + DataSnapshot childSnapshot = (DataSnapshot) children.next(); + todoText = todoText + " * " + childSnapshot.getValue().toString() + "\n"; + } + + // Now send the email + + // Note: When an application running in the development server calls the Mail + // service to send an email message, the message is printed to the log. + // The Java development server does not send the email message. + + // You can test the email without waiting for the cron job to run by + // loading http://[FIREBASE_PROJECT_ID].appspot.com/send-email in your browser. + + Properties props = new Properties(); + Session session = Session.getDefaultInstance(props, null); + try { + Message msg = new MimeMessage(session); + //Make sure you substitute your project-id in the email From field + msg.setFrom(new InternetAddress("reminder@fir-demo-d5acb.appspotmail.com", + "FirebaseDemoApp Admin")); + msg.addRecipient(Message.RecipientType.TO, + new InternetAddress("andrej@rasevicengineering.com", "Recipient")); + msg.addRecipient(Message.RecipientType.TO, + new InternetAddress("arasevic@cs.umd.edu", "Recipient")); + msg.setSubject("Things to do today"); + msg.addRecipient(Message.RecipientType.TO, + new InternetAddress("aporter@cs.umd.edu", "Recipient")); + msg.setText(todoText); + Transport.send(msg); + } catch (MessagingException | UnsupportedEncodingException e) { + Log.warning(e.getMessage()); + } + + // Note: in a production application you should replace the hard-coded email address + // above with code that populates msg.addRecipient with the app user's email address. + } + + @Override + public void onCancelled(DatabaseError error){ + System.out.println("Error: "+error); + } + }); + } +} \ No newline at end of file diff --git a/LectureExamples/FirebaseDemo/backend/src/main/webapp/WEB-INF/appengine-web.xml b/LectureExamples/FirebaseDemo/backend/src/main/webapp/WEB-INF/appengine-web.xml new file mode 100644 index 0000000000000000000000000000000000000000..6e84671245081f14765e4db92f4919381233fb19 --- /dev/null +++ b/LectureExamples/FirebaseDemo/backend/src/main/webapp/WEB-INF/appengine-web.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8"?> +<appengine-web-app xmlns="http://appengine.google.com/ns/1.0"> + <application>fir-demo-d5acb</application> + <version>1</version> + <threadsafe>true</threadsafe> + <manual-scaling> + <instances>1</instances> + </manual-scaling> + <system-properties> + <property name="java.util.logging.config.file" value="WEB-INF/logging.properties" /> + </system-properties> +</appengine-web-app> \ No newline at end of file diff --git a/LectureExamples/FirebaseDemo/backend/src/main/webapp/WEB-INF/logging.properties b/LectureExamples/FirebaseDemo/backend/src/main/webapp/WEB-INF/logging.properties new file mode 100644 index 0000000000000000000000000000000000000000..0c2ea51bc6da727b26f60ee12d303679e5b6efec --- /dev/null +++ b/LectureExamples/FirebaseDemo/backend/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: +# +# <system-properties> +# <property name="java.util.logging.config.file" value="WEB-INF/logging.properties"/> +# </system-properties> +# + +# Set the default logging level for all loggers to WARNING +.level = WARNING diff --git a/LectureExamples/FirebaseDemo/backend/src/main/webapp/WEB-INF/web.xml b/LectureExamples/FirebaseDemo/backend/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000000000000000000000000000000000000..ea2e361182d11ec1fe94fae75d1d92bce88de94a --- /dev/null +++ b/LectureExamples/FirebaseDemo/backend/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="utf-8"?> +<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"> + <servlet> + <servlet-name>MyServlet</servlet-name> + <servlet-class>com.example.andrej.rasevic.myapplication.backend.MyServlet</servlet-class> + </servlet> + <servlet-mapping> + <servlet-name>MyServlet</servlet-name> + <url-pattern>/send-email</url-pattern> + </servlet-mapping> + <welcome-file-list> + <welcome-file>index.html</welcome-file> + </welcome-file-list> +</web-app> \ No newline at end of file diff --git a/LectureExamples/FirebaseDemo/backend/src/main/webapp/index.html b/LectureExamples/FirebaseDemo/backend/src/main/webapp/index.html new file mode 100644 index 0000000000000000000000000000000000000000..4e6ae46f52516c266b9047aba31fd3f654c7341f --- /dev/null +++ b/LectureExamples/FirebaseDemo/backend/src/main/webapp/index.html @@ -0,0 +1,58 @@ +<!DOCTYPE html> +<html> +<head> + <title>Hello, App Engine!</title> + <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css"> + <link rel="stylesheet" + href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap-theme.min.css"> +</head> +<body role="document" style="padding-top: 70px;"> + +<div class="navbar navbar-inverse navbar-fixed-top" role="navigation"> + <div class="container"> + <div class="navbar-header"> + <a class="navbar-brand" href="#">Hello, App Engine!</a> + </div> + <div class="navbar-collapse collapse"> + <ul class="nav navbar-nav"> + <li><a href="https://developers.google.com/appengine/docs/java/">Google App Engine + documentation</a></li> + <li><a href="https://console.developers.google.com">Google Developers Console</a> + </li> + </ul> + </div> + </div> +</div> + +<div class="container theme-showcase" role="main"> + <div class="jumbotron"> + <div class="row"> + <div class="col-lg-12"> + <h1>Hello, App Engine!</h1> + <p>Enter your name and press the button below to call <code>MyServlet</code>.</p> + + <form action="/hello" method="POST"> + <div class="input-group"> + <input type="text" class="form-control input-lg" placeholder="Name" + name="name"/> + <span class="input-group-btn"> + <button class="btn btn-default btn-primary btn-group btn-lg" + type="submit" id="helloButton">Say "Hello";</button> + </span> + </div> + </form> + <br/> + <p>For more information about Google App Engine for Java, check out the <a + href="https://developers.google.com/appengine/docs/java/">App Engine + documentation</a>.</p> + <p>If you need step-by-step instructions for connecting your Android application to + this backend module, see <a + href="https://github.com/GoogleCloudPlatform/gradle-appengine-templates/tree/master/HelloWorld">"App + Engine Java Servlet Module" template documentation</a>.</p> + </div> + </div> + </div> +</div> + +</body> +</html> diff --git a/LectureExamples/FirebaseDemo/settings.gradle b/LectureExamples/FirebaseDemo/settings.gradle index e7b4def49cb53d9aa04228dd3edb14c9e635e003..dca702a6693f95ccd4fec303a84219a196597b48 100644 --- a/LectureExamples/FirebaseDemo/settings.gradle +++ b/LectureExamples/FirebaseDemo/settings.gradle @@ -1 +1 @@ -include ':app' +include ':app', ':backend'