├── .github
└── ISSUE_TEMPLATE
│ └── config.yml
├── .gitignore
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── android
├── FirebaseContinue
│ ├── build.gradle
│ ├── gradle.properties
│ ├── gradle
│ │ └── wrapper
│ │ │ ├── gradle-wrapper.jar
│ │ │ └── gradle-wrapper.properties
│ ├── gradlew
│ ├── gradlew.bat
│ ├── library
│ │ ├── build.gradle
│ │ └── src
│ │ │ └── main
│ │ │ ├── AndroidManifest.xml
│ │ │ ├── java
│ │ │ └── com
│ │ │ │ └── firebasecontinue
│ │ │ │ └── FirebaseContinue.java
│ │ │ └── res
│ │ │ └── values
│ │ │ └── public.xml
│ └── settings.gradle
└── README.md
├── chrome-extensions
├── README.md
└── firebase-continue.js
├── ios
├── .gitignore
├── FirebaseContinue
│ ├── Example
│ │ ├── FirebaseContinue.xcodeproj
│ │ │ ├── project.pbxproj
│ │ │ └── xcshareddata
│ │ │ │ └── xcschemes
│ │ │ │ └── FirebaseContinue-Example.xcscheme
│ │ ├── FirebaseContinue
│ │ │ ├── Base.lproj
│ │ │ │ ├── LaunchScreen.storyboard
│ │ │ │ └── Main.storyboard
│ │ │ ├── FCNAppDelegate.h
│ │ │ ├── FCNAppDelegate.m
│ │ │ ├── FCNViewController.h
│ │ │ ├── FCNViewController.m
│ │ │ ├── FirebaseContinue-Info.plist
│ │ │ ├── FirebaseContinue-Prefix.pch
│ │ │ ├── Images.xcassets
│ │ │ │ └── AppIcon.appiconset
│ │ │ │ │ └── Contents.json
│ │ │ ├── en.lproj
│ │ │ │ └── InfoPlist.strings
│ │ │ └── main.m
│ │ ├── Podfile
│ │ └── Tests
│ │ │ ├── Tests-Info.plist
│ │ │ ├── Tests-Prefix.pch
│ │ │ ├── Tests.m
│ │ │ └── en.lproj
│ │ │ └── InfoPlist.strings
│ ├── FirebaseContinue.podspec
│ ├── FirebaseContinue
│ │ ├── Assets
│ │ │ └── .gitkeep
│ │ └── Classes
│ │ │ ├── FCNContinue.h
│ │ │ └── FCNContinue.m
│ └── _Pods.xcodeproj
└── README.md
├── sample-firebase-continue-database.rules.json
└── samples
├── README.md
├── android
├── Continote
│ ├── app
│ │ ├── build.gradle
│ │ ├── libs
│ │ │ └── .gitkeep
│ │ └── src
│ │ │ └── main
│ │ │ ├── AndroidManifest.xml
│ │ │ ├── java
│ │ │ └── com
│ │ │ │ └── firebasecontinue
│ │ │ │ └── sample
│ │ │ │ └── continote
│ │ │ │ ├── BaseActivity.java
│ │ │ │ ├── EditNoteActivity.java
│ │ │ │ ├── MainActivity.java
│ │ │ │ ├── MyNotesActivity.java
│ │ │ │ ├── Note.java
│ │ │ │ └── NoteListItemViewHolder.java
│ │ │ └── res
│ │ │ ├── layout
│ │ │ ├── activity_edit_note.xml
│ │ │ ├── activity_main.xml
│ │ │ ├── activity_my_notes.xml
│ │ │ └── note_list_item.xml
│ │ │ ├── mipmap-hdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-ldpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-mdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxxhdpi
│ │ │ └── ic_launcher.png
│ │ │ └── values
│ │ │ ├── colors.xml
│ │ │ ├── dimens.xml
│ │ │ └── styles.xml
│ ├── build.gradle
│ ├── gradle.properties
│ ├── gradle
│ │ └── wrapper
│ │ │ ├── gradle-wrapper.jar
│ │ │ └── gradle-wrapper.properties
│ ├── gradlew
│ ├── gradlew.bat
│ ├── settings.gradle
│ └── setup-file-templates
│ │ └── sample-strings.xml
└── README.md
├── chrome-extension
├── Continote
│ ├── background.html
│ ├── images
│ │ └── icons
│ │ │ ├── icon-128.png
│ │ │ ├── icon-16.png
│ │ │ ├── icon-24.png
│ │ │ ├── icon-32.png
│ │ │ └── icon-48.png
│ ├── main-popup.html
│ ├── manifest.json
│ ├── scripts
│ │ ├── auth-helper.js
│ │ ├── background.js
│ │ ├── constants.js
│ │ ├── main-popup.js
│ │ ├── sample-config.js
│ │ ├── signin-popup.js
│ │ └── utils.js
│ ├── signin-popup.html
│ └── styles
│ │ └── all-popups.css
└── README.md
├── ios
├── Continote
│ ├── Continote.xcodeproj
│ │ ├── project.xcworkspace
│ │ │ └── contents.xcworkspacedata
│ │ └── sample-project.pbxproj
│ ├── Continote.xcworkspace
│ │ └── contents.xcworkspacedata
│ ├── Continote
│ │ ├── AppDelegate.swift
│ │ ├── Assets.xcassets
│ │ │ ├── AppIcon.appiconset
│ │ │ │ ├── Contents.json
│ │ │ │ ├── Icon-60@2x.png
│ │ │ │ ├── Icon-60@3x.png
│ │ │ │ ├── Icon-76@1x.png
│ │ │ │ ├── Icon-76@2x.png
│ │ │ │ └── Icon-83.5@2x.png
│ │ │ └── LaunchImage.launchimage
│ │ │ │ └── Contents.json
│ │ ├── Base.lproj
│ │ │ ├── LaunchScreen.storyboard
│ │ │ └── Main.storyboard
│ │ ├── BaseViewController.swift
│ │ ├── Continote-Bridging-Header.h
│ │ ├── EditNoteViewController.swift
│ │ ├── MainViewController.swift
│ │ ├── MyNotesTableViewCell.swift
│ │ ├── MyNotesTableViewDataSource.swift
│ │ ├── MyNotesViewController.swift
│ │ ├── Note.swift
│ │ ├── Sample-Constants.swift
│ │ ├── Utils.swift
│ │ └── sample-Info.plist
│ ├── Podfile
│ └── Podfile.lock
└── README.md
└── web
├── Continote
├── firebase.json
├── public
│ ├── 404.html
│ ├── edit-note.html
│ ├── images
│ │ └── favicon.ico
│ ├── index.html
│ ├── my-notes.html
│ ├── scripts
│ │ ├── auth-helper.js
│ │ ├── edit-note.js
│ │ ├── index.js
│ │ ├── my-notes.js
│ │ ├── sample-config.js
│ │ └── utils.js
│ └── styles
│ │ └── all-pages.css
└── sample-database.rules.json
└── README.md
/.github/ISSUE_TEMPLATE/config.yml:
--------------------------------------------------------------------------------
1 | blank_issues_enabled: false
2 | contact_links:
3 | - name: 🛑 Library Archived
4 | url: https://firebaseopensource.com/
5 | about: This repository is archived. Visit our open source site to browse other Firebase libraries.
6 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright (c) 2017 Google Inc. All Rights Reserved.
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | # in compliance with the License. You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software distributed under the
10 | # License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
11 | # express or implied. See the License for the specific language governing permissions and
12 | # limitations under the License.
13 | #
14 |
15 | # Intellij
16 | *.iml
17 | .idea
18 |
19 | # Android Studio
20 | captures/
21 | .externalNativeBuild
22 |
23 | # Gradle files
24 | .gradle/
25 | build/
26 |
27 | # Built Android application files
28 | *.apk
29 |
30 | # Local configuration file (ex. SDK path)
31 | local.properties
32 |
33 | # Google Services (ex. APIs and Firebase)
34 | google-services.json
35 | GoogleService-Info.plist
36 |
37 | # Firebase Hosting
38 | .firebaserc
39 | firebase-debug.log
40 |
41 | # Build generated
42 | build/
43 | DerivedData/
44 |
45 | # Various Xcode settings
46 | *.pbxuser
47 | !default.pbxuser
48 | *.mode1v3
49 | !default.mode1v3
50 | *.mode2v3
51 | !default.mode2v3
52 | *.perspectivev3
53 | !default.perspectivev3
54 | xcuserdata/
55 |
56 | # Other Xcode files
57 | *.moved-aside
58 | *.xccheckout
59 | *.xcscmblueprint
60 |
61 | # Obj-C/Swift specific
62 | *.hmap
63 | *.ipa
64 | *.dSYM.zip
65 | *.dSYM
66 |
67 | # CocoaPods
68 | Pods/
69 |
70 | # Chrome Extension related
71 | *.pem
72 | *.crx
73 |
74 | # Local config/setup
75 | database.rules.json
76 | samples/android/Continote/app/src/main/res/values/strings.xml
77 | samples/chrome-extension/Continote/scripts/config.js
78 | samples/ios/Continote/Continote/Constants.swift
79 | samples/ios/Continote/Continote/Info.plist
80 | samples/ios/Continote/Continote.xcodeproj/project.pbxproj
81 | samples/web/Continote/database.rules.json
82 | samples/web/Continote/public/scripts/config.js
83 |
84 | # Libraries for samples
85 | samples/android/Continote/app/libs/*.aar
86 | samples/chrome-extension/Continote/scripts/firebase-continue.js
87 | samples/ios/Continote/Continote/FCNContinue.h
88 | samples/ios/Continote/Continote/FCNContinue.m
89 |
90 | # Misc.
91 | .DS_Store
92 | *.swp
93 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contibuting to Firebase Continue
2 |
3 | Want to contribute? Great!
4 |
5 | First, please read this page (including the [the small print at the end](#the-small-print)).
6 |
7 | ## Table of Contents
8 |
9 | 1. [Before You Contribute](#before-you-contribute)
10 | 2. [Adding New Features](#adding-new-features)
11 | 3. [Code Reviews](#code-reviews)
12 | 4. [The Small Print](#the-small-print)
13 |
14 | ## Before You Contribute
15 |
16 | Before we can use your code, you must sign the [Google Individual Contributor
17 | License Agreement](https://cla.developers.google.com/about/google-individual)
18 | (CLA), which you can do online. The CLA is necessary mainly because you own the
19 | copyright to your changes, even after your contribution becomes part of our
20 | codebase, so we need your permission to use and distribute your code. We also
21 | need to be sure of various other things — for instance that you'll tell us if you
22 | know that your code infringes on other people's patents. You don't have to sign
23 | the CLA until after you've submitted your code for review and a member has
24 | approved it, but you must do it before we can put your code into our codebase.
25 |
26 | ## Adding New Features
27 |
28 | Before you start working on a larger contribution, you should get in touch with
29 | us first through the issue tracker with your idea so that we can help out and
30 | possibly guide you. Coordinating up front makes it much easier to avoid
31 | frustration later on.
32 |
33 | If this has been discussed in an issue, make sure to mention the issue number.
34 | If not, go file an issue about this to make sure this is a desirable change.
35 |
36 | ## Code Reviews
37 |
38 | All submissions, including submissions by project members, require review. We
39 | use GitHub pull requests for this purpose.
40 |
41 | ## The Small Print
42 |
43 | Contributions made by corporations are covered by a different agreement than the
44 | one above, the [Software Grant and Corporate Contributor License
45 | Agreement](https://cla.developers.google.com/about/google-corporate).
46 |
--------------------------------------------------------------------------------
/android/FirebaseContinue/build.gradle:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2017 Google Inc. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the
10 | * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
11 | * express or implied. See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 |
15 | buildscript {
16 | repositories {
17 | jcenter()
18 | }
19 |
20 | dependencies {
21 | classpath 'com.android.tools.build:gradle:2.3.3'
22 | }
23 | }
24 |
25 | allprojects {
26 | repositories {
27 | jcenter()
28 | }
29 | }
30 |
31 | task clean(type: Delete) {
32 | delete rootProject.buildDir
33 | }
34 |
--------------------------------------------------------------------------------
/android/FirebaseContinue/gradle.properties:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright (c) 2017 Google Inc. All Rights Reserved.
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | # in compliance with the License. You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software distributed under the
10 | # License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
11 | # express or implied. See the License for the specific language governing permissions and
12 | # limitations under the License.
13 | #
14 |
15 | # Project-wide Gradle settings.
16 |
17 | # IDE (e.g. Android Studio) users:
18 | # Gradle settings configured through the IDE *will override*
19 | # any settings specified in this file.
20 |
21 | # For more details on how to configure your build environment visit
22 | # http://www.gradle.org/docs/current/userguide/build_environment.html
23 |
24 | # Specifies the JVM arguments used for the daemon process.
25 | # The setting is particularly useful for tweaking memory settings.
26 | org.gradle.jvmargs=-Xmx1536m
27 |
28 | # When configured, Gradle will run in incubating parallel mode.
29 | # This option should only be used with decoupled projects. More details, visit
30 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
31 | # org.gradle.parallel=true
32 |
--------------------------------------------------------------------------------
/android/FirebaseContinue/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FirebaseExtended/firebase-continue/b8c94cad16a80efba152f20a0f652e38050611f9/android/FirebaseContinue/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/android/FirebaseContinue/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright (c) 2017 Google Inc. All Rights Reserved.
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | # in compliance with the License. You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software distributed under the
10 | # License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
11 | # express or implied. See the License for the specific language governing permissions and
12 | # limitations under the License.
13 | #
14 |
15 | #Mon Jul 31 16:51:28 EDT 2017
16 | distributionBase=GRADLE_USER_HOME
17 | distributionPath=wrapper/dists
18 | zipStoreBase=GRADLE_USER_HOME
19 | zipStorePath=wrapper/dists
20 | distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip
21 |
--------------------------------------------------------------------------------
/android/FirebaseContinue/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | #
4 | # Copyright (c) 2017 Google Inc. All Rights Reserved.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
7 | # in compliance with the License. You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software distributed under the
12 | # License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13 | # express or implied. See the License for the specific language governing permissions and
14 | # limitations under the License.
15 | #
16 |
17 | ##############################################################################
18 | ##
19 | ## Gradle start up script for UN*X
20 | ##
21 | ##############################################################################
22 |
23 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
24 | DEFAULT_JVM_OPTS=""
25 |
26 | APP_NAME="Gradle"
27 | APP_BASE_NAME=`basename "$0"`
28 |
29 | # Use the maximum available, or set MAX_FD != -1 to use that value.
30 | MAX_FD="maximum"
31 |
32 | warn ( ) {
33 | echo "$*"
34 | }
35 |
36 | die ( ) {
37 | echo
38 | echo "$*"
39 | echo
40 | exit 1
41 | }
42 |
43 | # OS specific support (must be 'true' or 'false').
44 | cygwin=false
45 | msys=false
46 | darwin=false
47 | case "`uname`" in
48 | CYGWIN* )
49 | cygwin=true
50 | ;;
51 | Darwin* )
52 | darwin=true
53 | ;;
54 | MINGW* )
55 | msys=true
56 | ;;
57 | esac
58 |
59 | # Attempt to set APP_HOME
60 | # Resolve links: $0 may be a link
61 | PRG="$0"
62 | # Need this for relative symlinks.
63 | while [ -h "$PRG" ] ; do
64 | ls=`ls -ld "$PRG"`
65 | link=`expr "$ls" : '.*-> \(.*\)$'`
66 | if expr "$link" : '/.*' > /dev/null; then
67 | PRG="$link"
68 | else
69 | PRG=`dirname "$PRG"`"/$link"
70 | fi
71 | done
72 | SAVED="`pwd`"
73 | cd "`dirname \"$PRG\"`/" >/dev/null
74 | APP_HOME="`pwd -P`"
75 | cd "$SAVED" >/dev/null
76 |
77 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
78 |
79 | # Determine the Java command to use to start the JVM.
80 | if [ -n "$JAVA_HOME" ] ; then
81 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
82 | # IBM's JDK on AIX uses strange locations for the executables
83 | JAVACMD="$JAVA_HOME/jre/sh/java"
84 | else
85 | JAVACMD="$JAVA_HOME/bin/java"
86 | fi
87 | if [ ! -x "$JAVACMD" ] ; then
88 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
89 |
90 | Please set the JAVA_HOME variable in your environment to match the
91 | location of your Java installation."
92 | fi
93 | else
94 | JAVACMD="java"
95 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
96 |
97 | Please set the JAVA_HOME variable in your environment to match the
98 | location of your Java installation."
99 | fi
100 |
101 | # Increase the maximum file descriptors if we can.
102 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
103 | MAX_FD_LIMIT=`ulimit -H -n`
104 | if [ $? -eq 0 ] ; then
105 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
106 | MAX_FD="$MAX_FD_LIMIT"
107 | fi
108 | ulimit -n $MAX_FD
109 | if [ $? -ne 0 ] ; then
110 | warn "Could not set maximum file descriptor limit: $MAX_FD"
111 | fi
112 | else
113 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
114 | fi
115 | fi
116 |
117 | # For Darwin, add options to specify how the application appears in the dock
118 | if $darwin; then
119 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
120 | fi
121 |
122 | # For Cygwin, switch paths to Windows format before running java
123 | if $cygwin ; then
124 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
125 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
126 | JAVACMD=`cygpath --unix "$JAVACMD"`
127 |
128 | # We build the pattern for arguments to be converted via cygpath
129 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
130 | SEP=""
131 | for dir in $ROOTDIRSRAW ; do
132 | ROOTDIRS="$ROOTDIRS$SEP$dir"
133 | SEP="|"
134 | done
135 | OURCYGPATTERN="(^($ROOTDIRS))"
136 | # Add a user-defined pattern to the cygpath arguments
137 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
138 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
139 | fi
140 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
141 | i=0
142 | for arg in "$@" ; do
143 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
144 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
145 |
146 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
147 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
148 | else
149 | eval `echo args$i`="\"$arg\""
150 | fi
151 | i=$((i+1))
152 | done
153 | case $i in
154 | (0) set -- ;;
155 | (1) set -- "$args0" ;;
156 | (2) set -- "$args0" "$args1" ;;
157 | (3) set -- "$args0" "$args1" "$args2" ;;
158 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
159 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
160 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
161 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
162 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
163 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
164 | esac
165 | fi
166 |
167 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
168 | function splitJvmOpts() {
169 | JVM_OPTS=("$@")
170 | }
171 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
172 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
173 |
174 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
175 |
--------------------------------------------------------------------------------
/android/FirebaseContinue/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 |
3 | @rem #
4 | @rem # Copyright (c) 2017 Google Inc. All Rights Reserved.
5 | @rem #
6 | @rem # Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
7 | @rem # except in compliance with the License. You may obtain a copy of the License at
8 | @rem #
9 | @rem # http://www.apache.org/licenses/LICENSE-2.0
10 | @rem #
11 | @rem # Unless required by applicable law or agreed to in writing, software distributed under the
12 | @rem # License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13 | @rem # either express or implied. See the License for the specific language governing permissions
14 | @rem # and limitations under the License.
15 | @rem #
16 |
17 | @rem ##########################################################################
18 | @rem
19 | @rem Gradle startup script for Windows
20 | @rem
21 | @rem ##########################################################################
22 |
23 | @rem Set local scope for the variables with windows NT shell
24 | if "%OS%"=="Windows_NT" setlocal
25 |
26 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
27 | set DEFAULT_JVM_OPTS=
28 |
29 | set DIRNAME=%~dp0
30 | if "%DIRNAME%" == "" set DIRNAME=.
31 | set APP_BASE_NAME=%~n0
32 | set APP_HOME=%DIRNAME%
33 |
34 | @rem Find java.exe
35 | if defined JAVA_HOME goto findJavaFromJavaHome
36 |
37 | set JAVA_EXE=java.exe
38 | %JAVA_EXE% -version >NUL 2>&1
39 | if "%ERRORLEVEL%" == "0" goto init
40 |
41 | echo.
42 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
43 | echo.
44 | echo Please set the JAVA_HOME variable in your environment to match the
45 | echo location of your Java installation.
46 |
47 | goto fail
48 |
49 | :findJavaFromJavaHome
50 | set JAVA_HOME=%JAVA_HOME:"=%
51 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
52 |
53 | if exist "%JAVA_EXE%" goto init
54 |
55 | echo.
56 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
57 | echo.
58 | echo Please set the JAVA_HOME variable in your environment to match the
59 | echo location of your Java installation.
60 |
61 | goto fail
62 |
63 | :init
64 | @rem Get command-line arguments, handling Windowz variants
65 |
66 | if not "%OS%" == "Windows_NT" goto win9xME_args
67 | if "%@eval[2+2]" == "4" goto 4NT_args
68 |
69 | :win9xME_args
70 | @rem Slurp the command line arguments.
71 | set CMD_LINE_ARGS=
72 | set _SKIP=2
73 |
74 | :win9xME_args_slurp
75 | if "x%~1" == "x" goto execute
76 |
77 | set CMD_LINE_ARGS=%*
78 | goto execute
79 |
80 | :4NT_args
81 | @rem Get arguments from the 4NT Shell from JP Software
82 | set CMD_LINE_ARGS=%$
83 |
84 | :execute
85 | @rem Setup the command line
86 |
87 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
88 |
89 | @rem Execute Gradle
90 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
91 |
92 | :end
93 | @rem End local scope for the variables with windows NT shell
94 | if "%ERRORLEVEL%"=="0" goto mainEnd
95 |
96 | :fail
97 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
98 | rem the _cmd.exe /c_ return code!
99 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
100 | exit /b 1
101 |
102 | :mainEnd
103 | if "%OS%"=="Windows_NT" endlocal
104 |
105 | :omega
106 |
--------------------------------------------------------------------------------
/android/FirebaseContinue/library/build.gradle:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2017 Google Inc. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the
10 | * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
11 | * express or implied. See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 |
15 | // TODO: Look into a more robust build process, possibly including minification for release builds
16 | // (look to FirebaseUI-Android for an example).
17 |
18 | apply plugin: 'com.android.library'
19 |
20 | android {
21 | compileSdkVersion 25
22 | buildToolsVersion '25.0.0'
23 |
24 | defaultConfig {
25 | minSdkVersion 14
26 | targetSdkVersion 25
27 |
28 | versionCode 1
29 | versionName '0.1.0'
30 | }
31 |
32 | buildTypes.all {
33 | minifyEnabled false
34 |
35 | // Rename the output file.
36 | libraryVariants.all { variant ->
37 | variant.outputs.each { output ->
38 | output.outputFile = new File(output.outputFile.parent,
39 | "FirebaseContinue-${defaultConfig.versionName}.aar")
40 | }
41 | }
42 | }
43 | }
44 |
45 | dependencies {
46 | // Firebase
47 | compile 'com.google.firebase:firebase-auth:11.0.0'
48 | compile 'com.google.firebase:firebase-database:11.0.0'
49 | }
50 |
--------------------------------------------------------------------------------
/android/FirebaseContinue/library/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
18 |
19 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/android/FirebaseContinue/library/src/main/res/values/public.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/android/FirebaseContinue/settings.gradle:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2017 Google Inc. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the
10 | * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
11 | * express or implied. See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 |
15 | include ':library'
16 |
--------------------------------------------------------------------------------
/ios/.gitignore:
--------------------------------------------------------------------------------
1 | # For libraries, this should not be checked in
2 | Podfile.lock
3 |
4 | # The workspace is generated
5 | *.xcworkspace
6 |
--------------------------------------------------------------------------------
/ios/FirebaseContinue/Example/FirebaseContinue.xcodeproj/xcshareddata/xcschemes/FirebaseContinue-Example.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
33 |
39 |
40 |
41 |
42 |
43 |
49 |
50 |
51 |
52 |
53 |
54 |
64 |
66 |
72 |
73 |
74 |
75 |
76 |
77 |
83 |
85 |
91 |
92 |
93 |
94 |
96 |
97 |
100 |
101 |
102 |
--------------------------------------------------------------------------------
/ios/FirebaseContinue/Example/FirebaseContinue/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/ios/FirebaseContinue/Example/FirebaseContinue/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/ios/FirebaseContinue/Example/FirebaseContinue/FCNAppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2017 Google Inc.
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License");
5 | // you may not use this file except in compliance with the License.
6 | // You may obtain a copy of the License at
7 | //
8 | // http://www.apache.org/licenses/LICENSE-2.0
9 | //
10 | // Unless required by applicable law or agreed to in writing, software
11 | // distributed under the License is distributed on an "AS IS" BASIS,
12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | // See the License for the specific language governing permissions and
14 | // limitations under the License.
15 | //
16 |
17 | @import UIKit;
18 |
19 | /**
20 | * Important Note: This is not a working example of using Firebase Continue.
21 | *
22 | * The Firebase Continue for iOS library is planned to eventually be available via Cocoapods
23 | * (rather than being required to manually copy-paste its source into your project), so this
24 | * Cocoapods-provided development environment lays the groundwork for that.
25 | *
26 | * For an actual, working sample of Firebase Continue, see the samples/ios subdirectory
27 | * from the root of the repository at:
28 | * https://github.com/firebase/firebase-continue/tree/master/samples/ios
29 | */
30 | @interface FCNAppDelegate : UIResponder
31 |
32 | @property(strong, nonatomic) UIWindow *window;
33 |
34 | @end
35 |
--------------------------------------------------------------------------------
/ios/FirebaseContinue/Example/FirebaseContinue/FCNAppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2017 Google Inc.
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License");
5 | // you may not use this file except in compliance with the License.
6 | // You may obtain a copy of the License at
7 | //
8 | // http://www.apache.org/licenses/LICENSE-2.0
9 | //
10 | // Unless required by applicable law or agreed to in writing, software
11 | // distributed under the License is distributed on an "AS IS" BASIS,
12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | // See the License for the specific language governing permissions and
14 | // limitations under the License.
15 | //
16 |
17 | #import "FCNAppDelegate.h"
18 |
19 | /**
20 | * Important Note: This is not a working example of using Firebase Continue.
21 | *
22 | * The Firebase Continue for iOS library is planned to eventually be available via Cocoapods
23 | * (rather than being required to manually copy-paste its source into your project), so this
24 | * Cocoapods-provided development environment lays the groundwork for that.
25 | *
26 | * For an actual, working sample of Firebase Continue, see the samples/ios subdirectory
27 | * from the root of the repository at:
28 | * https://github.com/firebase/firebase-continue/tree/master/samples/ios
29 | */
30 | @implementation FCNAppDelegate
31 |
32 | - (BOOL)application:(UIApplication *)application
33 | didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
34 | return YES;
35 | }
36 |
37 | @end
38 |
--------------------------------------------------------------------------------
/ios/FirebaseContinue/Example/FirebaseContinue/FCNViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2017 Google Inc.
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License");
5 | // you may not use this file except in compliance with the License.
6 | // You may obtain a copy of the License at
7 | //
8 | // http://www.apache.org/licenses/LICENSE-2.0
9 | //
10 | // Unless required by applicable law or agreed to in writing, software
11 | // distributed under the License is distributed on an "AS IS" BASIS,
12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | // See the License for the specific language governing permissions and
14 | // limitations under the License.
15 | //
16 |
17 | @import UIKit;
18 |
19 | /**
20 | * Important Note: This is not a working example of using Firebase Continue.
21 | *
22 | * The Firebase Continue for iOS library is planned to eventually be available via Cocoapods
23 | * (rather than being required to manually copy-paste its source into your project), so this
24 | * Cocoapods-provided development environment lays the groundwork for that.
25 | *
26 | * For an actual, working sample of Firebase Continue, see the samples/ios subdirectory
27 | * from the root of the repository at:
28 | * https://github.com/firebase/firebase-continue/tree/master/samples/ios
29 | */
30 | @interface FCNViewController : UIViewController
31 |
32 | @end
33 |
--------------------------------------------------------------------------------
/ios/FirebaseContinue/Example/FirebaseContinue/FCNViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2017 Google Inc.
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License");
5 | // you may not use this file except in compliance with the License.
6 | // You may obtain a copy of the License at
7 | //
8 | // http://www.apache.org/licenses/LICENSE-2.0
9 | //
10 | // Unless required by applicable law or agreed to in writing, software
11 | // distributed under the License is distributed on an "AS IS" BASIS,
12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | // See the License for the specific language governing permissions and
14 | // limitations under the License.
15 | //
16 |
17 | #import "FCNViewController.h"
18 |
19 | @import FirebaseContinue;
20 |
21 | /**
22 | * Important Note: This is not a working example of using Firebase Continue.
23 | *
24 | * The Firebase Continue for iOS library is planned to eventually be available via Cocoapods
25 | * (rather than being required to manually copy-paste its source into your project), so this
26 | * Cocoapods-provided development environment lays the groundwork for that.
27 | *
28 | * For an actual, working sample of Firebase Continue, see the samples/ios subdirectory
29 | * from the root of the repository at:
30 | * https://github.com/firebase/firebase-continue/tree/master/samples/ios
31 | */
32 | @implementation FCNViewController
33 |
34 | - (void)viewDidAppear:(BOOL)animated {
35 | [super viewDidAppear:animated];
36 |
37 | // Attempt to use Firebase Continue here. This should fail for any number of reasons,
38 | // including that Firebase has not been set up for this app.
39 | [FCNContinue broadcastToContinueActivityWithUrl:[TODO:YOUR-URL-TO-ALLOW-THE-USER-TO-
40 | CONTINUE-THEIR-ACTIVITY-HERE]
41 | withinApplicationWithName:[TODO:YOUR-APPLICATION-NAME-HERE]
42 | withCompletionBlock:^(NSError *_Nullable firebaseContinueError) {
43 | if (firebaseContinueError) {
44 | // The activity failed to broadcast.
45 | } else {
46 | // The activity was successfully broadcast.
47 |
48 | // An example use of this could be to inform the user to open
49 | // Chrome (with your Chrome extension installed which uses the
50 | // Firebase Continue for Chrome Extensions library), or their
51 | // macOS computer with Apple Handoff, if they wish continue their
52 | // activity there.
53 | }
54 | }];
55 | }
56 |
57 | @end
58 |
--------------------------------------------------------------------------------
/ios/FirebaseContinue/Example/FirebaseContinue/FirebaseContinue-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | ${PRODUCT_NAME}
9 | CFBundleExecutable
10 | ${EXECUTABLE_NAME}
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | ${PRODUCT_NAME}
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | 1.0
25 | LSRequiresIPhoneOS
26 |
27 | UILaunchStoryboardName
28 | LaunchScreen
29 | UIMainStoryboardFile
30 | Main
31 | UIRequiredDeviceCapabilities
32 |
33 | armv7
34 |
35 | UISupportedInterfaceOrientations
36 |
37 | UIInterfaceOrientationPortrait
38 | UIInterfaceOrientationLandscapeLeft
39 | UIInterfaceOrientationLandscapeRight
40 |
41 | UISupportedInterfaceOrientations~ipad
42 |
43 | UIInterfaceOrientationPortrait
44 | UIInterfaceOrientationPortraitUpsideDown
45 | UIInterfaceOrientationLandscapeLeft
46 | UIInterfaceOrientationLandscapeRight
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/ios/FirebaseContinue/Example/FirebaseContinue/FirebaseContinue-Prefix.pch:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2017 Google Inc.
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License");
5 | // you may not use this file except in compliance with the License.
6 | // You may obtain a copy of the License at
7 | //
8 | // http://www.apache.org/licenses/LICENSE-2.0
9 | //
10 | // Unless required by applicable law or agreed to in writing, software
11 | // distributed under the License is distributed on an "AS IS" BASIS,
12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | // See the License for the specific language governing permissions and
14 | // limitations under the License.
15 | //
16 |
17 | #import
18 |
19 | #ifndef __IPHONE_5_0
20 | #warning "This project uses features only available in iOS SDK 5.0 and later."
21 | #endif
22 |
23 | #ifdef __OBJC__
24 | @import UIKit;
25 | @import Foundation;
26 | #endif
27 |
--------------------------------------------------------------------------------
/ios/FirebaseContinue/Example/FirebaseContinue/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "size" : "1024x1024",
91 | "scale" : "1x"
92 | }
93 | ],
94 | "info" : {
95 | "version" : 1,
96 | "author" : "xcode"
97 | }
98 | }
--------------------------------------------------------------------------------
/ios/FirebaseContinue/Example/FirebaseContinue/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /* Localized versions of Info.plist keys */
2 |
--------------------------------------------------------------------------------
/ios/FirebaseContinue/Example/FirebaseContinue/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2017 Google Inc.
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License");
5 | // you may not use this file except in compliance with the License.
6 | // You may obtain a copy of the License at
7 | //
8 | // http://www.apache.org/licenses/LICENSE-2.0
9 | //
10 | // Unless required by applicable law or agreed to in writing, software
11 | // distributed under the License is distributed on an "AS IS" BASIS,
12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | // See the License for the specific language governing permissions and
14 | // limitations under the License.
15 | //
16 |
17 | @import UIKit;
18 |
19 | #import "FCNAppDelegate.h"
20 |
21 | /**
22 | * Important Note: This is not a working example of using Firebase Continue.
23 | *
24 | * The Firebase Continue for iOS library is planned to eventually be available via Cocoapods
25 | * (rather than being required to manually copy-paste its source into your project), so this
26 | * Cocoapods-provided development environment lays the groundwork for that.
27 | *
28 | * For an actual, working sample of Firebase Continue, see the samples/ios subdirectory
29 | * from the root of the repository at:
30 | * https://github.com/firebase/firebase-continue/tree/master/samples/ios
31 | */
32 | int main(int argc, char *argv[]) {
33 | @autoreleasepool {
34 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([FCNAppDelegate class]));
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/ios/FirebaseContinue/Example/Podfile:
--------------------------------------------------------------------------------
1 | use_frameworks!
2 |
3 | target 'FirebaseContinue_Example' do
4 | pod 'FirebaseContinue', :path => '../'
5 |
6 | target 'FirebaseContinue_Tests' do
7 | inherit! :search_paths
8 |
9 | end
10 | end
11 |
--------------------------------------------------------------------------------
/ios/FirebaseContinue/Example/Tests/Tests-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundlePackageType
14 | BNDL
15 | CFBundleShortVersionString
16 | 1.0
17 | CFBundleSignature
18 | ????
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/ios/FirebaseContinue/Example/Tests/Tests-Prefix.pch:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2017 Google Inc.
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License");
5 | // you may not use this file except in compliance with the License.
6 | // You may obtain a copy of the License at
7 | //
8 | // http://www.apache.org/licenses/LICENSE-2.0
9 | //
10 | // Unless required by applicable law or agreed to in writing, software
11 | // distributed under the License is distributed on an "AS IS" BASIS,
12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | // See the License for the specific language governing permissions and
14 | // limitations under the License.
15 | //
16 |
17 | #ifdef __OBJC__
18 |
19 |
20 |
21 | #endif
22 |
--------------------------------------------------------------------------------
/ios/FirebaseContinue/Example/Tests/Tests.m:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2017 Google Inc.
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License");
5 | // you may not use this file except in compliance with the License.
6 | // You may obtain a copy of the License at
7 | //
8 | // http://www.apache.org/licenses/LICENSE-2.0
9 | //
10 | // Unless required by applicable law or agreed to in writing, software
11 | // distributed under the License is distributed on an "AS IS" BASIS,
12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | // See the License for the specific language governing permissions and
14 | // limitations under the License.
15 | //
16 |
17 | @import XCTest;
18 |
19 | @interface Tests : XCTestCase
20 |
21 | @end
22 |
23 | @implementation Tests
24 |
25 | - (void)setUp
26 | {
27 | [super setUp];
28 | // Put setup code here. This method is called before the invocation of each test method in the class.
29 | }
30 |
31 | - (void)tearDown
32 | {
33 | // Put teardown code here. This method is called after the invocation of each test method in the class.
34 | [super tearDown];
35 | }
36 |
37 | - (void)testExample
38 | {
39 | XCTFail(@"No implementation for \"%s\"", __PRETTY_FUNCTION__);
40 | }
41 |
42 | @end
43 |
44 |
--------------------------------------------------------------------------------
/ios/FirebaseContinue/Example/Tests/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /* Localized versions of Info.plist keys */
2 |
3 |
--------------------------------------------------------------------------------
/ios/FirebaseContinue/FirebaseContinue.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |s|
2 | s.name = 'FirebaseContinue'
3 | s.version = '0.1.0'
4 | s.summary = 'Firebase Continue enables mobile developers to integrate activity transitioning from their mobile apps to the web.'
5 |
6 | s.description = <<-DESC
7 | Firebase Continue for iOS enables iOS developers to easily integrate activity transitioning
8 | from their apps to the web by way of Chrome extensions (or Apple Handoff for users with both an
9 | iOS device and macOS computer that are Apple Handoff enabled).
10 | DESC
11 |
12 | s.homepage = 'https://github.com/firebase/firebase-continue'
13 | s.license = { :type => 'Apache 2.0', :file => '../../LICENSE' }
14 | s.authors = 'Google, Inc'
15 | s.source = { :git => 'https://github.com/firebase/firebase-continue.git', :tag => s.version.to_s }
16 |
17 | s.ios.deployment_target = '8.0'
18 |
19 | s.source_files = 'FirebaseContinue/Classes/**/*'
20 |
21 | s.public_header_files = 'FirebaseContinue/Classes/**/*.h'
22 | end
23 |
--------------------------------------------------------------------------------
/ios/FirebaseContinue/FirebaseContinue/Assets/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FirebaseExtended/firebase-continue/b8c94cad16a80efba152f20a0f652e38050611f9/ios/FirebaseContinue/FirebaseContinue/Assets/.gitkeep
--------------------------------------------------------------------------------
/ios/FirebaseContinue/FirebaseContinue/Classes/FCNContinue.h:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2017 Google Inc.
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License");
5 | // you may not use this file except in compliance with the License.
6 | // You may obtain a copy of the License at
7 | //
8 | // http://www.apache.org/licenses/LICENSE-2.0
9 | //
10 | // Unless required by applicable law or agreed to in writing, software
11 | // distributed under the License is distributed on an "AS IS" BASIS,
12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | // See the License for the specific language governing permissions and
14 | // limitations under the License.
15 | //
16 |
17 | @import Foundation;
18 |
19 | NS_ASSUME_NONNULL_BEGIN
20 |
21 | /**
22 | * A block which is invoked on the main thread when something the Firebase Continue library
23 | * attempted to do asynchronously completed. The error provided to the block will be non-nil if
24 | * the it was unsuccessful. See the library method documentation below for more details.
25 | */
26 | typedef void (^FCNContinueCompletionBlock)(NSError *_Nullable firebaseContinueError);
27 |
28 | /**
29 | * @class FCNContinue
30 | * @brief The Firebase Continue for iOS library.
31 | *
32 | * Firebase Continue enables developers to easily integrate activity transitioning from their
33 | * iOS apps to the web, by way of Firebase and Chrome extensions (or Apple Handoff for users with
34 | * both an iOS device and macOS computer that are Apple Handoff enabled).
35 | * For more details, see: https://github.com/firebase/firebase-continue
36 | *
37 | * Please see the usage instructions in the relevant README file(s).
38 | * There is also more specific documentation within the library itself below.
39 | *
40 | * TODO: Add unit tests, including tests while the app/Firebase is offline.
41 | */
42 | @interface FCNContinue : NSObject
43 |
44 | /**
45 | * Attempts to asynchronously broadcast an Activity (codified as a URL) within an application
46 | * that the currently signed in user may wish to continue elsewhere (in the immediate future)
47 | * to all potential clients (ex. Chrome extension(s) and/or Apple Handoff enabled macOS computers)
48 | * which could allow the user to do so by opening said URL.
49 | *
50 | * Note that, by design, only the most recently successfully broadcast Activity (for a given
51 | * application) could possibly be relevant to the user. The Firebase Continue database rules
52 | * and libraries enforce this. For more details, please see the relevant README file(s).
53 | *
54 | * @param activityUrl The URL which, if the current user were to navigate to, would allow the user
55 | * to continue their Activity.
56 | * @param applicationName The name of the application, as defined in the Firebase Realtime
57 | * Database rules for Firebase Continue, that the user's Activity is within.
58 | * @param completionBlock An optional completion block which is invoked on the main thread when the
59 | * broadcast attempt is complete. The error provided to the block will be non-nil if the broadcast
60 | * was unsuccessful.
61 | */
62 | + (void)broadcastToContinueActivityWithUrl:(NSString *)activityUrl
63 | withinApplicationWithName:(NSString *)applicationName
64 | withCompletionBlock:(nullable FCNContinueCompletionBlock)completionBlock
65 | NS_SWIFT_NAME(broadcastToContinueActivity(withUrl:withinApplication:onComplete:));
66 |
67 | /**
68 | * TODO: Possibly add a "dismissActivityToContinue" method akin to dismissing within the Chrome
69 | * extensions library. This could be used by mobile apps when an Activity that was broadcast would
70 | * certainly no longer be relevant to the user (rather than letting the Chrome extension library
71 | * itself (or the user within a Chrome extension) decide that).
72 | */
73 |
74 | - (id)init __attribute__((unavailable("FCNContinue cannot be instantiated")));
75 |
76 | @end
77 |
78 | NS_ASSUME_NONNULL_END
79 |
--------------------------------------------------------------------------------
/ios/FirebaseContinue/_Pods.xcodeproj:
--------------------------------------------------------------------------------
1 | Example/Pods/Pods.xcodeproj
--------------------------------------------------------------------------------
/sample-firebase-continue-database.rules.json:
--------------------------------------------------------------------------------
1 | {
2 | "rules": {
3 |
4 | // Disallow all data reading and writing by default.
5 | // This will be overridden in specific cases.
6 | ".read": false,
7 | ".write": false,
8 |
9 | [TODO: YOUR-APPLICATION'S-OTHER-FIREBASE-REALTIME-DATABASE-RULES-HERE]
10 |
11 | // This node holds all Firebase Continue specific data.
12 | "firebaseContinue": {
13 |
14 | // Firebase Continue has support for multiple applications using the same
15 | // Firebase project, so we need to separate each application (in this
16 | // sample's case, only "[TODO: YOUR-APPLICATION-NAME-HERE]") into its own
17 | // child node directly under firebaseContinue here.
18 | "$application": {
19 |
20 | // Firebase Continue data is user specific. Furthermore, we only need
21 | // to store at most one data point per user (per application): the data
22 | // for the activity the user most recently may wish to continue elsewhere.
23 | // Finally, a data point is essentially immutable: it can either be
24 | // added or deleted, but the library never has a need to update it.
25 | "$uid": {
26 |
27 | // The ".read" and ".write" security rules first ensure that Firebase Continue
28 | // data is user specific. Then, they ensure the data is for an application which you,
29 | // the developer, have specifically listed here.
30 | //
31 | // Important Reminder: Remember to use the exact same application name when required
32 | // while using the various Firebase Continue libraries.
33 | //
34 | // To support multiple applications within one Firebase project, simply modify the
35 | // ".read" and ".write" rules below like so:
36 | // ".read": "$uid === auth.uid && ($application === 'someappname' || $application === 'otherappname')",
37 | // ".write": "$uid === auth.uid && ($application === 'someappname' || $application === 'otherappname')",
38 | ".read": "$uid === auth.uid && $application === '[TODO: YOUR-APPLICATION-NAME-HERE]'",
39 | ".write": "$uid === auth.uid && $application === '[TODO: YOUR-APPLICATION-NAME-HERE]'",
40 |
41 | ".validate": "!data.exists() && newData.hasChildren(['metadata', 'url'])",
42 |
43 | // This is the metadata for this Firebase Continue data point.
44 | // It allows the library to determine relevancy.
45 | // Note: the metadata should never need to be updated - data points
46 | // are either added or removed altogether.
47 | "metadata": {
48 | ".validate": "newData.hasChildren(['addedAt'])",
49 |
50 | // This is a timestamp denoting when the data point was added to
51 | // Firebase. We ensure that this value is between now and 5 minutes
52 | // in the past, since that is the window of time that
53 | // Firebase Continue data is considered relevant.
54 | "addedAt": {
55 | ".validate": "newData.isNumber() && newData.val() >= (now - 300000) && newData.val() <= now"
56 | },
57 |
58 | // Prevent extraneous data from being added to the metadata.
59 | "$other": {
60 | ".validate": false
61 | }
62 | },
63 |
64 | // This is the URL which, if navigated to by the user, would allow
65 | // them to continue their activity elsewhere.
66 | // The URL validation is from:
67 | // https://firebase.google.com/docs/reference/security/database/regex#usage
68 | // Note: the URL should never need to be updated - data points are
69 | // either added or removed altogether.
70 | "url": {
71 | ".validate": "newData.isString() && newData.val().matches(/^(ht|f)tp(s?):\\/\\/[0-9a-zA-Z]([-.\\w]*[0-9a-zA-Z])*((0-9)*)*(\\/?)([a-zA-Z0-9\\-\\.\\?\\,\\'\\/\\\\+&=%\\$#_]*)?$/)"
72 | },
73 |
74 | // Prevent extraneous data from being added to this data point.
75 | "$other": {
76 | ".validate": false
77 | }
78 | }
79 | }
80 | }
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/samples/README.md:
--------------------------------------------------------------------------------
1 | # Firebase Continue Samples - "Continote" Application
2 |
3 | This directory contains a set of Firebase Continue samples, collectively titled
4 | "Continote".
5 |
6 | "Continote" allows users to begin writing plaintext notes in either the
7 | [Android sample app](android) or the [iOS sample app](ios), and then continue
8 | writing in Chrome from exactly where they are thanks to the
9 | [sample Chrome extension](chrome-extension)
10 | (or [Apple Handoff](https://developer.apple.com/handoff/),
11 | for users with both an iOS device running "Continote" and
12 | macOS computer) opening a link to the correct location in the [sample web app](web).
13 |
14 | All of the samples provided here are designed to be used with the same
15 | Firebase project.
16 |
17 | It is strongly recommended that you create a new Firebase project specifically
18 | for the "Continote" samples.
19 | See the [Initial Setup guide](#initial-setup) below for more details.
20 |
21 | ## Table of Contents
22 |
23 | 1. [Initial Setup](#initial-setup)
24 | 2. [Usage](#usage)
25 | 3. [Compatibility](#compatibility)
26 | 4. [Dependencies](#dependencies)
27 |
28 | ## Initial Setup
29 |
30 | After completing the following steps, you will have properly set up a Firebase
31 | project to be able to try the Firebase Continue samples, collectively titled
32 | "Continote":
33 |
34 | 1. First, if you have not already done so, either download a copy of this
35 | repository from the Releases page to get a stable version of
36 | Firebase Continue (including its samples),
37 | or clone the repository locally for an unstable, development version.
38 |
39 | 2. [Create a Firebase project](https://firebase.google.com/)
40 | to use for the Continote samples.
41 |
42 | Note that [Firebase offers a free plan](https://firebase.google.com/pricing/)
43 | which you may be able to take advantage of.
44 |
45 | **Reminder**: Firebase Continue, and thus these samples, requires use of
46 | [Firebase Authentication](https://firebase.google.com/products/auth/)
47 | and the
48 | [Firebase Realtime Database](https://firebase.google.com/products/database/)
49 | for your project. Furthermore, the Firebase Realtime Database rules for Continote
50 | will be applied to your project, and the
51 | [sample web app](web) will be deployed to
52 | [Firebase Hosting](https://firebase.google.com/products/hosting/),
53 | using the
54 | [Firebase CLI](https://firebase.google.com/docs/cli/).
55 |
56 | 3. Enable signing in with Google for your Firebase project:
57 |
58 | 1. In the [Firebase console](https://console.firebase.google.com/)
59 | for your project, open the Authentication section.
60 |
61 | 2. On the Sign in method tab, enable the Google sign-in method, and click
62 | **Save**.
63 |
64 | 4. Enable signing in with Facebook for your Firebase project:
65 |
66 | 1. On the [Facebook for Developers website](https://developers.facebook.com/),
67 | create an app for use with the Continote samples.
68 |
69 | 2. Make note of the **name** you gave your new Facebook app, as well as its
70 | **App ID** and **App Secret** as you will need those values for this and
71 | other Continote samples.
72 |
73 | 3. In the [Firebase console](https://console.firebase.google.com/)
74 | for your project, open the Authentication section.
75 |
76 | 4. On the SIGN-IN METHOD tab, enable the Facebook sign-in method and
77 | specify the App ID and App Secret from above, and click **Save**.
78 |
79 | 5. Within that same Facebook sign-in method dialog, copy your OAuth redirect URI
80 | (ex. `my-app-12345.firebaseapp.com/__/auth/handler`)
81 | and add it to your "Valid OAuth redirect URIs" in your Facebook app's settings
82 | on the [Facebook for Developers website](https://developers.facebook.com/)
83 | in the Product Settings > Facebook Login configuration page.
84 |
85 | 5. [Follow the setup guide for the Continote sample web app](web#setup),
86 | since doing so will also apply the necessary Firebase Realtime Database rules
87 | for both Firebase Continue and Continote itself to your Firebase project.
88 |
89 | 6. Done!
90 |
91 | You can now follow the other setup guides for each Continote
92 | sample you plan on trying (for example, the
93 | [sample Chrome extension](chrome-extension#setup) and the
94 | [sample iOS app](ios#setup)).
95 |
96 | ## Usage
97 |
98 | Please see each sample subdirectory for relevant usage guides.
99 |
100 | ## Compatibility
101 |
102 | Please see each sample subdirectory for relevant compatibility information.
103 |
104 | ## Dependencies
105 |
106 | Please see each sample subdirectory for relevant dependency information.
107 |
--------------------------------------------------------------------------------
/samples/android/Continote/app/build.gradle:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2017 Google Inc. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the
10 | * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
11 | * express or implied. See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 |
15 | apply plugin: 'com.android.application'
16 |
17 | android {
18 | compileSdkVersion 25
19 | buildToolsVersion '25.0.0'
20 |
21 | defaultConfig {
22 | applicationId 'com.firebasecontinue.sample.continote'
23 | minSdkVersion 16
24 | targetSdkVersion 25
25 | versionCode 1
26 | versionName '0.1.0'
27 | }
28 |
29 | buildTypes.all {
30 | minifyEnabled false
31 |
32 | // Rename the output file.
33 | applicationVariants.all { variant ->
34 | variant.outputs.each { output ->
35 | output.outputFile = new File(output.outputFile.parent,
36 | "Continote-${defaultConfig.versionName}.apk")
37 | }
38 | }
39 | }
40 | }
41 |
42 | dependencies {
43 | // Android support libraries
44 | compile 'com.android.support:appcompat-v7:25.0.0'
45 | compile 'com.android.support:design:25.0.0'
46 | compile 'com.android.support:support-annotations:25.0.0'
47 | compile 'com.android.support.constraint:constraint-layout:1.0.0'
48 |
49 | // Firebase
50 | compile 'com.google.firebase:firebase-auth:11.0.0'
51 | compile 'com.google.firebase:firebase-database:11.0.0'
52 |
53 | // Firebase Continue
54 | // TODO: Include non-local version of Firebase Continue and remove local libs folder when
55 | // the Firebase Continue for Android library v0.1.0 is released.
56 | compile(name: 'FirebaseContinue-0.1.0', ext: 'aar')
57 |
58 | // FirebaseUI
59 | compile 'com.firebaseui:firebase-ui-auth:2.0.0'
60 | compile 'com.firebaseui:firebase-ui-database:2.0.0'
61 |
62 | // Required by FirebaseUI for signing in via Facebook.
63 | compile 'com.facebook.android:facebook-android-sdk:4.22.0'
64 | }
65 |
66 | apply plugin: 'com.google.gms.google-services'
67 |
--------------------------------------------------------------------------------
/samples/android/Continote/app/libs/.gitkeep:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright (c) 2017 Google Inc. All Rights Reserved.
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | # in compliance with the License. You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software distributed under the
10 | # License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
11 | # express or implied. See the License for the specific language governing permissions and
12 | # limitations under the License.
13 | #
14 |
--------------------------------------------------------------------------------
/samples/android/Continote/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
18 |
19 |
21 |
22 |
23 |
24 |
29 |
30 |
31 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
47 |
48 |
49 |
50 |
54 |
55 |
56 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/samples/android/Continote/app/src/main/java/com/firebasecontinue/sample/continote/BaseActivity.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2017 Google Inc. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the
10 | * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
11 | * express or implied. See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 |
15 | package com.firebasecontinue.sample.continote;
16 |
17 | import android.support.annotation.StringRes;
18 | import android.support.design.widget.Snackbar;
19 | import android.support.v7.app.AppCompatActivity;
20 | import android.view.View;
21 |
22 | import com.google.firebase.auth.FirebaseAuth;
23 | import com.google.firebase.auth.FirebaseUser;
24 |
25 | /**
26 | * The abstract Activity which all other Activities in this app must subclass.
27 | *
28 | * It provides functionality needed by all Activities, such as setting up Firebase Auth to listen
29 | * for authentication state changes.
30 | */
31 | public abstract class BaseActivity extends AppCompatActivity {
32 |
33 | // Firebase-related
34 | private final FirebaseAuth.AuthStateListener mHandleAuthStateChanged =
35 | new FirebaseAuth.AuthStateListener() {
36 | @Override
37 | public void onAuthStateChanged(FirebaseAuth firebaseAuth) {
38 | FirebaseUser user = firebaseAuth.getCurrentUser();
39 | if (user != null) {
40 | // Since the user object is non-null, the current user is now signed in.
41 | BaseActivity.this.handleUserSignedIn(user);
42 | } else {
43 | // Since the user object is null, the current user is now signed out.
44 | BaseActivity.this.handleUserSignedOut();
45 | }
46 | }
47 | };
48 |
49 | @Override
50 | protected void onStart() {
51 | super.onStart();
52 |
53 | // Start listening for Firebase Auth state changes.
54 | FirebaseAuth.getInstance().addAuthStateListener(mHandleAuthStateChanged);
55 | }
56 |
57 | @Override
58 | protected void onStop() {
59 | super.onStop();
60 |
61 | // Stop listening for Firebase Auth state changes.
62 | FirebaseAuth.getInstance().removeAuthStateListener(mHandleAuthStateChanged);
63 | }
64 |
65 | /**
66 | * Displays the provided message in a snackbar.
67 | *
68 | * See: https://developer.android.com/reference/android/support/design/widget/Snackbar.html
69 | */
70 | protected void showSnackbar(@StringRes final int messageRes) {
71 | runOnUiThread(new Runnable() {
72 | public void run() {
73 | View rootView = findViewById(android.R.id.content);
74 | if (rootView != null) {
75 | Snackbar.make(rootView, messageRes, Snackbar.LENGTH_LONG).show();
76 | }
77 | }
78 | });
79 | }
80 |
81 | /**
82 | * Determines and then returns whether or not the current user is signed in.
83 | *
84 | * @return true iff the current user is signed into this app, false otherwise.
85 | */
86 | protected boolean currentUserIsSignedIn() {
87 | return FirebaseAuth.getInstance().getCurrentUser() != null;
88 | }
89 |
90 | /**
91 | * Handles when the user signs in.
92 | *
93 | * Override in subclasses to respond to this authentication state change.
94 | *
95 | * @param user The user who is now signed in.
96 | */
97 | protected void handleUserSignedIn(FirebaseUser user) {}
98 |
99 | /**
100 | * Handles when the user signs out.
101 | *
102 | * Override in subclasses to respond to this authentication state change.
103 | */
104 | protected void handleUserSignedOut() {}
105 | }
106 |
--------------------------------------------------------------------------------
/samples/android/Continote/app/src/main/java/com/firebasecontinue/sample/continote/Note.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2017 Google Inc. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the
10 | * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
11 | * express or implied. See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 |
15 | package com.firebasecontinue.sample.continote;
16 |
17 | import android.support.annotation.Nullable;
18 |
19 | /**
20 | * A Note for the user within Continote.
21 | * The schema of each Note is outlined in sample-database.rules.json within the web sample.
22 | */
23 | public class Note {
24 |
25 | // The title of this Note.
26 | @Nullable
27 | private String mTitle = null;
28 |
29 | // The main content of this Note.
30 | @Nullable
31 | private String mContent = null;
32 |
33 | /**
34 | * Constructs a default Note without any values.
35 | *
36 | * This is necessary for Firebase to be able to create a new instance of this class.
37 | */
38 | public Note() {}
39 |
40 | /**
41 | * Constructs a new Note instance with the provided values.
42 | *
43 | * Important reminder:
44 | * Changes to Notes (such as creating a new Note) on the client-side do not automatically
45 | * propagate to the Firebase Realtime Database.
46 | *
47 | * @param title The title of the Note.
48 | * @param content The main content of the Note.
49 | */
50 | public Note(@Nullable String title, @Nullable String content) {
51 | mTitle = title;
52 | mContent = content;
53 | }
54 |
55 | /**
56 | * Gets and returns the title of this Note.
57 | *
58 | * @return The title of this Note.
59 | */
60 | @Nullable
61 | public String getTitle() {
62 | return mTitle;
63 | }
64 |
65 | /**
66 | * Gets and returns the main content of this Note.
67 | *
68 | * @return The main content of this Note.
69 | */
70 | @Nullable
71 | public String getContent() {
72 | return mContent;
73 | }
74 |
75 | /**
76 | * Sets the title of this Note on the client-side.
77 | *
78 | * This is necessary for Firebase to create and update Note instances.
79 | *
80 | * @param title The new title of this Note.
81 | */
82 | public void setTitle(@Nullable String title) {
83 | mTitle = title;
84 | }
85 |
86 | /**
87 | * Sets the main content of this Note on the client-side.
88 | *
89 | * This is necessary for Firebase to create and update Note instances.
90 | *
91 | * @param content The new main content of this Note.
92 | */
93 | public void setContent(@Nullable String content) {
94 | mContent = content;
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/samples/android/Continote/app/src/main/java/com/firebasecontinue/sample/continote/NoteListItemViewHolder.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2017 Google Inc. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the
10 | * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
11 | * express or implied. See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 |
15 | package com.firebasecontinue.sample.continote;
16 |
17 | import android.graphics.Typeface;
18 | import android.support.annotation.Nullable;
19 | import android.text.TextUtils;
20 | import android.view.View;
21 | import android.widget.TextView;
22 |
23 | /**
24 | * The ListView within MyNotesActivity is filled with items managed by these ViewHolders
25 | * (one per Note).
26 | *
27 | * For more details about the ViewHolder design pattern, see:
28 | * https://developer.android.com/training/improving-layouts/smooth-scrolling.html
29 | */
30 | public class NoteListItemViewHolder {
31 |
32 | // The key from the Firebase Realtime Database for the Note this ViewHolder represents.
33 | // This is passed to the EditNoteActivity.
34 | @Nullable
35 | private String mNoteDatabaseKey = null;
36 |
37 | /**
38 | * Constructs a new NoteListItemViewHolder instance for the provided View and Note combination.
39 | *
40 | * @param itemView The View managed by this ViewHolder.
41 | * @param note The Note this ViewHolder is for.
42 | * @param databaseKey The database key of the Note this ViewHolder is for.
43 | */
44 | public NoteListItemViewHolder(View itemView, Note note, String databaseKey) {
45 | if (itemView == null || note == null || TextUtils.isEmpty(databaseKey)) {
46 | // This should not happen, but just in case.
47 | throw new AssertionError("itemView, note, and database key must be non-null/non-empty");
48 | }
49 |
50 | update(itemView, note, databaseKey);
51 | }
52 |
53 | /**
54 | * Updates this ViewHolder and the UI of the View managed by it based on the provided Note and
55 | * database key.
56 | *
57 | * @param itemView The View managed by this ViewHolder which may need its UI updated.
58 | * @param note The Note this ViewHolder is for (to update the UI based on).
59 | * @param databaseKey The database key of the Note this ViewHolder is for.
60 | */
61 | public void update(View itemView, Note note, String databaseKey) {
62 | if (itemView == null || note == null || TextUtils.isEmpty(databaseKey)) {
63 | // This should not happen, but just in case.
64 | throw new AssertionError("itemView, note, and database key must be non-null/non-empty");
65 | }
66 |
67 | mNoteDatabaseKey = databaseKey;
68 |
69 | TextView titleTextView = (TextView) itemView.findViewById(R.id.noteItemTitleTextView);
70 | setTextWithPlaceholder(titleTextView, note.getTitle(), "No Title");
71 | TextView contentTextView = (TextView) itemView.findViewById(R.id.noteItemContentTextView);
72 | setTextWithPlaceholder(contentTextView, note.getContent(), "No Content");
73 | }
74 |
75 | /**
76 | * Gets and returns Note database key.
77 | *
78 | * @return The Firebase Realtime Database key for the Note this ViewHolder is for.
79 | */
80 | @Nullable
81 | public String getNoteDatabaseKey() {
82 | return mNoteDatabaseKey;
83 | }
84 |
85 | /**
86 | * Sets the text of the provided textView to the provided value, or the placeholder if the
87 | * value is null or empty. Also italicizes the textView if the placeholder is used.
88 | *
89 | * This could go into a "Utils" class, but this is the only place it is used, so this
90 | * is sufficient for this sample app.
91 | *
92 | * @param textView The TextView to set the text for.
93 | * @param value The value to set the text to.
94 | * @param placeholder The placeholder text to use if the value above is null or empty.
95 | */
96 | private static void setTextWithPlaceholder(TextView textView,
97 | @Nullable String value,
98 | @Nullable String placeholder) {
99 | if (!TextUtils.isEmpty(value)) {
100 | // The provided value is nonempty, so use it.
101 | textView.setText(value);
102 | textView.setTypeface(textView.getTypeface(), Typeface.NORMAL);
103 | } else {
104 | // The provided value is empty, so use the placeholder.
105 | textView.setText(placeholder);
106 | textView.setTypeface(textView.getTypeface(), Typeface.ITALIC);
107 | }
108 | }
109 | }
110 |
--------------------------------------------------------------------------------
/samples/android/Continote/app/src/main/res/layout/activity_edit_note.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
18 |
19 |
29 |
30 |
43 |
44 |
55 |
56 |
57 |
66 |
67 |
81 |
82 |
99 |
100 |
112 |
113 |
124 |
125 |
126 |
127 |
128 |
--------------------------------------------------------------------------------
/samples/android/Continote/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
18 |
19 |
29 |
30 |
43 |
44 |
56 |
57 |
70 |
71 |
72 |
--------------------------------------------------------------------------------
/samples/android/Continote/app/src/main/res/layout/activity_my_notes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
18 |
19 |
29 |
30 |
47 |
48 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/samples/android/Continote/app/src/main/res/layout/note_list_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
18 |
19 |
30 |
31 |
45 |
46 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/samples/android/Continote/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FirebaseExtended/firebase-continue/b8c94cad16a80efba152f20a0f652e38050611f9/samples/android/Continote/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/samples/android/Continote/app/src/main/res/mipmap-ldpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FirebaseExtended/firebase-continue/b8c94cad16a80efba152f20a0f652e38050611f9/samples/android/Continote/app/src/main/res/mipmap-ldpi/ic_launcher.png
--------------------------------------------------------------------------------
/samples/android/Continote/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FirebaseExtended/firebase-continue/b8c94cad16a80efba152f20a0f652e38050611f9/samples/android/Continote/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/samples/android/Continote/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FirebaseExtended/firebase-continue/b8c94cad16a80efba152f20a0f652e38050611f9/samples/android/Continote/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/samples/android/Continote/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FirebaseExtended/firebase-continue/b8c94cad16a80efba152f20a0f652e38050611f9/samples/android/Continote/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/samples/android/Continote/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FirebaseExtended/firebase-continue/b8c94cad16a80efba152f20a0f652e38050611f9/samples/android/Continote/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/samples/android/Continote/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
18 |
19 |
20 | #ffc107
21 | #deab13
22 | #ffab40
23 | @android:color/black
24 |
25 |
--------------------------------------------------------------------------------
/samples/android/Continote/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
18 |
19 |
20 | 16dp
21 | 8dp
22 | 8dp
23 | 1dp
24 |
25 |
--------------------------------------------------------------------------------
/samples/android/Continote/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
18 |
19 |
20 |
21 |
22 |
29 |
30 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/samples/android/Continote/build.gradle:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2017 Google Inc. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the
10 | * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
11 | * express or implied. See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 |
15 | buildscript {
16 | repositories {
17 | jcenter()
18 | }
19 |
20 | dependencies {
21 | classpath 'com.android.tools.build:gradle:2.3.3'
22 | classpath 'com.google.gms:google-services:3.0.0'
23 | }
24 | }
25 |
26 | allprojects {
27 | repositories {
28 | jcenter()
29 |
30 | flatDir {
31 | dirs 'libs'
32 | }
33 | }
34 | }
35 |
36 | task clean(type: Delete) {
37 | delete rootProject.buildDir
38 | }
39 |
--------------------------------------------------------------------------------
/samples/android/Continote/gradle.properties:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright (c) 2017 Google Inc. All Rights Reserved.
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | # in compliance with the License. You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software distributed under the
10 | # License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
11 | # express or implied. See the License for the specific language governing permissions and
12 | # limitations under the License.
13 | #
14 |
15 | # Project-wide Gradle settings.
16 |
17 | # IDE (e.g. Android Studio) users:
18 | # Gradle settings configured through the IDE *will override*
19 | # any settings specified in this file.
20 |
21 | # For more details on how to configure your build environment visit
22 | # http://www.gradle.org/docs/current/userguide/build_environment.html
23 |
24 | # Specifies the JVM arguments used for the daemon process.
25 | # The setting is particularly useful for tweaking memory settings.
26 | org.gradle.jvmargs=-Xmx1536m
27 |
28 | # When configured, Gradle will run in incubating parallel mode.
29 | # This option should only be used with decoupled projects. More details, visit
30 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
31 | # org.gradle.parallel=true
32 |
--------------------------------------------------------------------------------
/samples/android/Continote/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FirebaseExtended/firebase-continue/b8c94cad16a80efba152f20a0f652e38050611f9/samples/android/Continote/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/samples/android/Continote/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright (c) 2017 Google Inc. All Rights Reserved.
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | # in compliance with the License. You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software distributed under the
10 | # License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
11 | # express or implied. See the License for the specific language governing permissions and
12 | # limitations under the License.
13 | #
14 |
15 | #Fri Jul 28 22:27:17 EDT 2017
16 | distributionBase=GRADLE_USER_HOME
17 | distributionPath=wrapper/dists
18 | zipStoreBase=GRADLE_USER_HOME
19 | zipStorePath=wrapper/dists
20 | distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip
21 |
--------------------------------------------------------------------------------
/samples/android/Continote/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | #
4 | # Copyright (c) 2017 Google Inc. All Rights Reserved.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
7 | # in compliance with the License. You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software distributed under the
12 | # License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13 | # express or implied. See the License for the specific language governing permissions and
14 | # limitations under the License.
15 | #
16 |
17 | ##############################################################################
18 | ##
19 | ## Gradle start up script for UN*X
20 | ##
21 | ##############################################################################
22 |
23 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
24 | DEFAULT_JVM_OPTS=""
25 |
26 | APP_NAME="Gradle"
27 | APP_BASE_NAME=`basename "$0"`
28 |
29 | # Use the maximum available, or set MAX_FD != -1 to use that value.
30 | MAX_FD="maximum"
31 |
32 | warn ( ) {
33 | echo "$*"
34 | }
35 |
36 | die ( ) {
37 | echo
38 | echo "$*"
39 | echo
40 | exit 1
41 | }
42 |
43 | # OS specific support (must be 'true' or 'false').
44 | cygwin=false
45 | msys=false
46 | darwin=false
47 | case "`uname`" in
48 | CYGWIN* )
49 | cygwin=true
50 | ;;
51 | Darwin* )
52 | darwin=true
53 | ;;
54 | MINGW* )
55 | msys=true
56 | ;;
57 | esac
58 |
59 | # Attempt to set APP_HOME
60 | # Resolve links: $0 may be a link
61 | PRG="$0"
62 | # Need this for relative symlinks.
63 | while [ -h "$PRG" ] ; do
64 | ls=`ls -ld "$PRG"`
65 | link=`expr "$ls" : '.*-> \(.*\)$'`
66 | if expr "$link" : '/.*' > /dev/null; then
67 | PRG="$link"
68 | else
69 | PRG=`dirname "$PRG"`"/$link"
70 | fi
71 | done
72 | SAVED="`pwd`"
73 | cd "`dirname \"$PRG\"`/" >/dev/null
74 | APP_HOME="`pwd -P`"
75 | cd "$SAVED" >/dev/null
76 |
77 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
78 |
79 | # Determine the Java command to use to start the JVM.
80 | if [ -n "$JAVA_HOME" ] ; then
81 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
82 | # IBM's JDK on AIX uses strange locations for the executables
83 | JAVACMD="$JAVA_HOME/jre/sh/java"
84 | else
85 | JAVACMD="$JAVA_HOME/bin/java"
86 | fi
87 | if [ ! -x "$JAVACMD" ] ; then
88 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
89 |
90 | Please set the JAVA_HOME variable in your environment to match the
91 | location of your Java installation."
92 | fi
93 | else
94 | JAVACMD="java"
95 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
96 |
97 | Please set the JAVA_HOME variable in your environment to match the
98 | location of your Java installation."
99 | fi
100 |
101 | # Increase the maximum file descriptors if we can.
102 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
103 | MAX_FD_LIMIT=`ulimit -H -n`
104 | if [ $? -eq 0 ] ; then
105 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
106 | MAX_FD="$MAX_FD_LIMIT"
107 | fi
108 | ulimit -n $MAX_FD
109 | if [ $? -ne 0 ] ; then
110 | warn "Could not set maximum file descriptor limit: $MAX_FD"
111 | fi
112 | else
113 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
114 | fi
115 | fi
116 |
117 | # For Darwin, add options to specify how the application appears in the dock
118 | if $darwin; then
119 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
120 | fi
121 |
122 | # For Cygwin, switch paths to Windows format before running java
123 | if $cygwin ; then
124 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
125 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
126 | JAVACMD=`cygpath --unix "$JAVACMD"`
127 |
128 | # We build the pattern for arguments to be converted via cygpath
129 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
130 | SEP=""
131 | for dir in $ROOTDIRSRAW ; do
132 | ROOTDIRS="$ROOTDIRS$SEP$dir"
133 | SEP="|"
134 | done
135 | OURCYGPATTERN="(^($ROOTDIRS))"
136 | # Add a user-defined pattern to the cygpath arguments
137 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
138 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
139 | fi
140 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
141 | i=0
142 | for arg in "$@" ; do
143 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
144 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
145 |
146 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
147 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
148 | else
149 | eval `echo args$i`="\"$arg\""
150 | fi
151 | i=$((i+1))
152 | done
153 | case $i in
154 | (0) set -- ;;
155 | (1) set -- "$args0" ;;
156 | (2) set -- "$args0" "$args1" ;;
157 | (3) set -- "$args0" "$args1" "$args2" ;;
158 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
159 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
160 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
161 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
162 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
163 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
164 | esac
165 | fi
166 |
167 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
168 | function splitJvmOpts() {
169 | JVM_OPTS=("$@")
170 | }
171 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
172 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
173 |
174 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
175 |
--------------------------------------------------------------------------------
/samples/android/Continote/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 |
3 | @rem #
4 | @rem # Copyright (c) 2017 Google Inc. All Rights Reserved.
5 | @rem #
6 | @rem # Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
7 | @rem # except in compliance with the License. You may obtain a copy of the License at
8 | @rem #
9 | @rem # http://www.apache.org/licenses/LICENSE-2.0
10 | @rem #
11 | @rem # Unless required by applicable law or agreed to in writing, software distributed under the
12 | @rem # License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13 | @rem # either express or implied. See the License for the specific language governing permissions
14 | @rem # and limitations under the License.
15 | @rem #
16 |
17 | @rem ##########################################################################
18 | @rem
19 | @rem Gradle startup script for Windows
20 | @rem
21 | @rem ##########################################################################
22 |
23 | @rem Set local scope for the variables with windows NT shell
24 | if "%OS%"=="Windows_NT" setlocal
25 |
26 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
27 | set DEFAULT_JVM_OPTS=
28 |
29 | set DIRNAME=%~dp0
30 | if "%DIRNAME%" == "" set DIRNAME=.
31 | set APP_BASE_NAME=%~n0
32 | set APP_HOME=%DIRNAME%
33 |
34 | @rem Find java.exe
35 | if defined JAVA_HOME goto findJavaFromJavaHome
36 |
37 | set JAVA_EXE=java.exe
38 | %JAVA_EXE% -version >NUL 2>&1
39 | if "%ERRORLEVEL%" == "0" goto init
40 |
41 | echo.
42 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
43 | echo.
44 | echo Please set the JAVA_HOME variable in your environment to match the
45 | echo location of your Java installation.
46 |
47 | goto fail
48 |
49 | :findJavaFromJavaHome
50 | set JAVA_HOME=%JAVA_HOME:"=%
51 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
52 |
53 | if exist "%JAVA_EXE%" goto init
54 |
55 | echo.
56 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
57 | echo.
58 | echo Please set the JAVA_HOME variable in your environment to match the
59 | echo location of your Java installation.
60 |
61 | goto fail
62 |
63 | :init
64 | @rem Get command-line arguments, handling Windowz variants
65 |
66 | if not "%OS%" == "Windows_NT" goto win9xME_args
67 | if "%@eval[2+2]" == "4" goto 4NT_args
68 |
69 | :win9xME_args
70 | @rem Slurp the command line arguments.
71 | set CMD_LINE_ARGS=
72 | set _SKIP=2
73 |
74 | :win9xME_args_slurp
75 | if "x%~1" == "x" goto execute
76 |
77 | set CMD_LINE_ARGS=%*
78 | goto execute
79 |
80 | :4NT_args
81 | @rem Get arguments from the 4NT Shell from JP Software
82 | set CMD_LINE_ARGS=%$
83 |
84 | :execute
85 | @rem Setup the command line
86 |
87 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
88 |
89 | @rem Execute Gradle
90 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
91 |
92 | :end
93 | @rem End local scope for the variables with windows NT shell
94 | if "%ERRORLEVEL%"=="0" goto mainEnd
95 |
96 | :fail
97 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
98 | rem the _cmd.exe /c_ return code!
99 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
100 | exit /b 1
101 |
102 | :mainEnd
103 | if "%OS%"=="Windows_NT" endlocal
104 |
105 | :omega
106 |
--------------------------------------------------------------------------------
/samples/android/Continote/settings.gradle:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2017 Google Inc. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the
10 | * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
11 | * express or implied. See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 |
15 | include ':app'
16 |
--------------------------------------------------------------------------------
/samples/android/Continote/setup-file-templates/sample-strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
18 |
19 |
20 |
21 | Continote
22 |
23 |
24 |
25 |
26 | Continote
27 |
28 |
29 | My Notes
30 |
31 |
32 | Edit Note
33 |
34 |
35 |
36 |
37 | continote
38 |
39 |
40 | [TODO: YOUR-FIREBASE-HOSTING-URL-FOR-CONTINOTE-WEB-HERE]/edit-note.html?noteKey=%1$s
41 |
42 |
43 |
44 |
45 | [TODO: YOUR-FACEBOOK-APP-ID-HERE]
46 |
47 |
48 | fb[TODO: YOUR-FACEBOOK-APP-ID-HERE]
49 |
50 |
51 |
55 |
56 | databaseKey
57 |
58 |
59 |
60 |
61 | Please sign in below to use %1$s.
62 |
63 |
64 | Hello %1$s!\nYou are currently signed in as %2$s.
65 |
66 |
67 |
68 |
69 | Sign In
70 |
71 |
72 | Sign Out
73 |
74 |
75 |
76 |
77 | My Notes
78 |
79 |
80 |
81 |
82 | + Write a new note
83 |
84 |
85 |
86 |
87 | Save
88 |
89 |
90 |
91 |
92 | Continue writing in Chrome
93 |
94 |
95 |
96 |
97 | Delete this note?
98 |
99 |
100 | If you choose to delete this note, it will be gone forever!
101 |
102 |
103 | Yes, delete it
104 |
105 |
106 | No, do not delete it
107 |
108 |
109 |
110 |
111 | Note not found.\n\nPlease go back to the My Notes screen and try again.
112 |
113 |
114 | Title
115 |
116 |
117 | Content
118 |
119 |
120 |
121 |
122 | Note saved successfully!
123 |
124 |
125 | Please open Chrome now and use the Continote extension to continue writing.
126 |
127 |
128 |
129 |
130 | Signing out failed. Please try again.
131 |
132 |
133 | Could not create a new note. Please try again.
134 |
135 |
136 | Could not delete note. Please try again.
137 |
138 |
139 | Could not save note. Please try again.
140 |
141 |
142 | Something went wrong. Please try again.
143 |
144 |
145 |
146 |
--------------------------------------------------------------------------------
/samples/chrome-extension/Continote/background.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 | Continote - Firebase Continue Chrome Extension Sample - Background Page
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 | This page can be used for debugging purposes via Chrome Developer Tools.
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/samples/chrome-extension/Continote/images/icons/icon-128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FirebaseExtended/firebase-continue/b8c94cad16a80efba152f20a0f652e38050611f9/samples/chrome-extension/Continote/images/icons/icon-128.png
--------------------------------------------------------------------------------
/samples/chrome-extension/Continote/images/icons/icon-16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FirebaseExtended/firebase-continue/b8c94cad16a80efba152f20a0f652e38050611f9/samples/chrome-extension/Continote/images/icons/icon-16.png
--------------------------------------------------------------------------------
/samples/chrome-extension/Continote/images/icons/icon-24.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FirebaseExtended/firebase-continue/b8c94cad16a80efba152f20a0f652e38050611f9/samples/chrome-extension/Continote/images/icons/icon-24.png
--------------------------------------------------------------------------------
/samples/chrome-extension/Continote/images/icons/icon-32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FirebaseExtended/firebase-continue/b8c94cad16a80efba152f20a0f652e38050611f9/samples/chrome-extension/Continote/images/icons/icon-32.png
--------------------------------------------------------------------------------
/samples/chrome-extension/Continote/images/icons/icon-48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FirebaseExtended/firebase-continue/b8c94cad16a80efba152f20a0f652e38050611f9/samples/chrome-extension/Continote/images/icons/icon-48.png
--------------------------------------------------------------------------------
/samples/chrome-extension/Continote/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "manifest_version": 2,
3 |
4 | "name": "Continote",
5 | "description": "Sample Chrome extension using the Firebase Continue library.",
6 | "version": "0.1.0",
7 |
8 | "permissions": [
9 | "notifications"
10 | ],
11 |
12 | "icons": {
13 | "16": "images/icons/icon-16.png",
14 | "48": "images/icons/icon-48.png",
15 | "128": "images/icons/icon-128.png"
16 | },
17 |
18 | "background": {
19 | "page": "background.html"
20 | },
21 |
22 | "browser_action": {
23 | "default_popup": "main-popup.html",
24 |
25 | "default_icon": {
26 | "16": "images/icons/icon-16.png",
27 | "24": "images/icons/icon-24.png",
28 | "32": "images/icons/icon-32.png"
29 | }
30 | },
31 |
32 | "content_security_policy": "script-src style-src img-src media-src object-src 'self' https://www.gstatic.com/ https://*.firebaseio.com https://cdn.firebase.com https://www.googleapis.com https://apis.google.com https://code.getmdl.io"
33 | }
34 |
--------------------------------------------------------------------------------
/samples/chrome-extension/Continote/scripts/constants.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2017 Google Inc. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a
6 | * copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations
14 | * under the License.
15 | */
16 |
17 | /**
18 | * This object provides global constants.
19 | *
20 | * Remember to include this script in the of a page if you plan on
21 | * using any of these constants within that page.
22 | *
23 | * @type {!Object}
24 | * @const
25 | */
26 | var Constants = (function() {
27 | 'use strict';
28 |
29 | return {
30 |
31 | /**
32 | * The name of this application.
33 | * This is used to get the Firebase Continue instance for Continote.
34 | *
35 | * @type {!string}
36 | * @const
37 | */
38 | appName: "continote"
39 | }
40 | }());
41 |
--------------------------------------------------------------------------------
/samples/chrome-extension/Continote/scripts/sample-config.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2017 Google Inc. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a
6 | * copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations
14 | * under the License.
15 | */
16 |
17 | /**
18 | * This script sets up Firebase.
19 | *
20 | * Remember to include this script in the of a page if you plan on using
21 | * Firebase within that page.
22 | *
23 | * TODO: Consider setting up a "common" folder for the Chrome extension sample
24 | * and the web app sample to share code, and putting this script there since it
25 | * currently overlaps (as of July 14, 2017). If this change is made, remember
26 | * to update the installation/setup guide!
27 | */
28 | (function() {
29 | 'use strict';
30 |
31 | /**
32 | * Firebase will be initialized with this config object.
33 | *
34 | * @type {!Object}
35 | * @const
36 | */
37 | var config_ = {
38 | apiKey: "[TODO: YOUR-API-KEY-HERE]",
39 | authDomain: "[TODO: YOUR-AUTH-DOMAIN-HERE]",
40 | databaseURL: "[TODO: YOUR-DATABASE-URL-HERE]",
41 | projectId: "[TODO: YOUR-PROJECT-ID-HERE]"
42 | };
43 | firebase.initializeApp(config_);
44 | })();
45 |
--------------------------------------------------------------------------------
/samples/chrome-extension/Continote/scripts/utils.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2017 Google Inc. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a
6 | * copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations
14 | * under the License.
15 | */
16 |
17 | /**
18 | * This object provides some simple utility functions.
19 | *
20 | * Remember to include this script in the of a page if you plan on
21 | * using any of these utilities within that page.
22 | *
23 | * @type {!Object}
24 | * @const
25 | */
26 | var Utils = (function() {
27 | 'use strict';
28 |
29 | /**
30 | * This is the class which, if applied to an element, hides that element.
31 | *
32 | * @type {!string}
33 | * @const
34 | */
35 | var hiddenClass_ = "hidden";
36 |
37 | /**
38 | * This is the name of the click event type.
39 | *
40 | * @type {!string}
41 | * @const
42 | */
43 | var clickEventType_ = "click";
44 |
45 | return {
46 | /**
47 | * Shows the provided DOM element if it is currently hidden.
48 | *
49 | * @function
50 | * @param {!Element} element
51 | * @const
52 | */
53 | showElement: function(element) {
54 | element.classList.remove(hiddenClass_);
55 | },
56 |
57 | /**
58 | * Hides the provided DOM element if it is currently shown.
59 | *
60 | * @function
61 | * @param {!Element} element
62 | * @const
63 | */
64 | hideElement: function(element) {
65 | element.classList.add(hiddenClass_);
66 | },
67 |
68 | /**
69 | * Enables the provided button element if it is currently disabled,
70 | * and adds the provided click event listener to the button
71 | * if the event listener is not already attached to it.
72 | *
73 | * @function
74 | * @param {!Element} button
75 | * @param {?ClickEventListener} clickEventListener
76 | * @const
77 | */
78 | enableButtonAndAddClickListener: function(button, clickEventListener) {
79 | button.disabled = false;
80 | if (clickEventListener) {
81 | button.addEventListener(clickEventType_, clickEventListener);
82 | }
83 | },
84 |
85 | /**
86 | * Disables the provided button element if it is currently enabled,
87 | * and removes the provided click event listener from the button
88 | * if the event listener is currently attached to it.
89 | *
90 | * @function
91 | * @param {!Element} button
92 | * @param {?ClickEventListener} clickEventListener
93 | * @const
94 | */
95 | disableButtonAndRemoveClickListener: function(button, clickEventListener) {
96 | button.disabled = true;
97 | if (clickEventListener) {
98 | button.removeEventListener(clickEventType_, clickEventListener);
99 | }
100 | }
101 | }
102 | }());
103 |
104 | // Below are extra JSDoc definitions to describe the callback functions
105 | // this utility object expects.
106 |
107 | /**
108 | * The standard click event callback.
109 | *
110 | * @callback ClickEventListener
111 | * @param {!Object} event
112 | */
113 |
--------------------------------------------------------------------------------
/samples/chrome-extension/Continote/signin-popup.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 | Continote - Firebase Continue Sample - Sign In
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
45 |
47 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
85 | You may close this window and use the extension by clicking its icon button
86 | again.
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 | Sign in here
102 |
103 |
104 |
105 |
106 | Please choose a platform to sign in with below to use the Continote extension.
107 |
108 |
109 |
110 |
111 |
112 |
117 |
118 |
119 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
--------------------------------------------------------------------------------
/samples/chrome-extension/Continote/styles/all-popups.css:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2017 Google Inc. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the
10 | * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
11 | * express or implied. See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 |
15 | /**
16 | * These styles apply to all popup pages.
17 | * They are based on the Material Design Lite samples provided here:
18 | * https://getmdl.io/templates/index.html
19 | */
20 |
21 | html,
22 | body {
23 | margin: 0;
24 | padding: 0;
25 | width: 500px;
26 | min-height: 300px;
27 | font-family: 'Roboto', 'Helvetica', sans-serif;
28 | }
29 |
30 | .mdl-layout__header-row {
31 | padding-left: 16px;
32 | }
33 |
34 | .app-title {
35 | font-weight: bold;
36 | }
37 |
38 | .mdl-layout__content {
39 | padding: 20px;
40 | }
41 |
42 | section:not(:last-child) {
43 | margin-bottom: 20px !important;
44 | }
45 |
46 | .mdl-card {
47 | height: auto;
48 | min-height: 0;
49 | display: -webkit-flex;
50 | display: -ms-flexbox;
51 | display: flex;
52 | -webkit-flex-direction: column;
53 | -ms-flex-direction: column;
54 | flex-direction: column;
55 | }
56 |
57 | .mdl-card > * {
58 | height: auto;
59 | }
60 |
61 | .mdl-card .mdl-card__title {
62 | padding: 10px 10px 0;
63 | }
64 |
65 | .mdl-card .mdl-card__supporting-text {
66 | margin: 10px;
67 | padding: 0;
68 | -webkit-flex-grow: 1;
69 | flex-grow: 1;
70 | }
71 |
72 | .mdl-card__actions {
73 | margin: 0;
74 | padding: 10px;
75 | }
76 |
77 | .hidden {
78 | display: none;
79 | }
80 |
--------------------------------------------------------------------------------
/samples/chrome-extension/README.md:
--------------------------------------------------------------------------------
1 | # Firebase Continue Samples - "Continote" Chrome Extension
2 |
3 | This directory contains a sample Chrome extension titled "Continote" which uses
4 | the Firebase Continue for Chrome Extensions library.
5 |
6 | In both the [Android sample app](../android) and the [iOS sample app](../ios),
7 | after a user taps to continue writing their note in Chrome, this extension
8 | allows them to complete that process by opening a link to the
9 | ["Continote" sample web app](../web) to exactly where they left off.
10 |
11 | ## Table of Contents
12 |
13 | 1. [Prerequisites](#prerequisites)
14 | 2. [Setup](#setup)
15 | 3. [Usage](#usage)
16 | 4. [Compatibility](#compatibility)
17 | 5. [Dependencies](#dependencies)
18 | 6. [Disclaimer](#disclaimer)
19 |
20 | ## Prerequisites
21 |
22 | Before proceeding to the [Setup section](#setup) below, you
23 | must first follow the [main `samples` README](../) so that you have a properly
24 | configured Firebase project for this and any other "Continote" samples
25 | you run.
26 |
27 | ## Setup
28 |
29 | After completing the following steps, you will have a properly configured instance of
30 | this sample packaged and installed to try out:
31 |
32 | 1. First, make sure you followed the [Prerequisites section](#prerequisites) above.
33 |
34 | 2. Copy the `firebase-continue.js` Chrome extensions library file
35 | from the Chrome extensions library directory at
36 | [`../../chrome-extensions/`](../../chrome-extensions)
37 | and paste a copy of it in the
38 | [`Continote/scripts/`](Continote/scripts/) directory.
39 |
40 | 3. Copy the `sample-config.js` file from the
41 | [`Continote/scripts/`](Continote/scripts)
42 | directory and paste a copy of it also in
43 | [`Continote/scripts/`](Continote/scripts).
44 |
45 | 4. Rename the `sample-config.js` copy to `config.js`.
46 |
47 | 5. Open `config.js` and fill out the clearly marked *[TODO: YOUR-VALUE-HERE]* details
48 | with the values for your Firebase project which should be listed in the
49 | [initialization code snippet](https://firebase.google.com/docs/web/setup#add_firebase_to_your_app)
50 | for it.
51 |
52 | For example:
53 |
54 | ```javascript
55 | var config_ = {
56 | apiKey: "abcdef123456",
57 | authDomain: "SomeFirebaseProjectName.firebaseapp.com",
58 | databaseURL: "https://SomeFirebaseProjectName.firebaseio.com",
59 | projectId: "SomeFirebaseProjectName"
60 | };
61 | ```
62 |
63 | 6. Package and install the extension to Chrome:
64 |
65 | 1. Open Google Chrome if you are not already using it.
66 |
67 | 2. Go to [chrome://extensions](chrome://extensions) to view and modify the
68 | extensions currently installed to your browser.
69 |
70 | 3. If it is not already checked, enable "Developer mode" by clicking the
71 | "Developer mode" checkbox at the top of your
72 | [chrome://extensions](chrome://extensions) page.
73 |
74 | 4. Click the "Pack extension..." button at the top of the page.
75 |
76 | 5. In the "Pack Extension" dialog that appears:
77 |
78 | 1. For the "Extension root directory", choose [`Continote/`](Continote).
79 |
80 | 2. For the "Private key file", choose nothing since this initial packaging
81 | and installing will generate a private key file for you to use in
82 | the future.
83 |
84 | 6. Click the "Pack Extension" to package the extension (i.e. generate
85 | installation and private key files).
86 |
87 | 7. Make note of where your extenion's `Continote.crx` and `Continote.pem` files
88 | were generated (most likely, they could be generated in this directory).
89 |
90 | **Keep your `Continote.pem` key file in a safe place.
91 | You will need it to package and install new versions of your extension.**
92 |
93 | 8. Navigate to where your `Continote.crx` file is, and drag it onto the
94 | [chrome://extensions](chrome://extensions) page in Chrome to install
95 | your extension.
96 |
97 | 9. Make note of your extension's **ID** on that page. You will need it later.
98 |
99 | 7. [Whitelist your Chrome extension ID in Firebase](https://firebase.google.com/docs/auth/web/google-signin#authenticate_with_firebase_in_a_chrome_extension)
100 | to allow Firebase Authentication within the extension.
101 |
102 | 8. Done!
103 |
104 | **Important Reminder**:
105 | If you make any changes to the code of your Chrome extension, remember
106 | to repeat the "package and install" step of this setup guide with one difference:
107 | provide the "Pack Extension" dialog with your private key file that was generated
108 | the first time you packaged and installed the extension. This is so that
109 | the packaging updates your existing Chrome extension, instead of creating
110 | a new Chrome extension with a new ID.
111 |
112 | ## Usage
113 |
114 | After this sample is properly set up and installed to your Chrome browser,
115 | open it by clicking its
116 | [browser action icon button](https://developer.chrome.com/extensions/browserAction).
117 |
118 | From there, you will be asked to sign in to be able to receive notifications to
119 | continue writing notes.
120 |
121 | ## Compatibility
122 |
123 | This sample Chrome extension is compatible with the
124 | [same versions of Chrome as the Firebase Continue library itself](../../chrome-extensions/#compatibility).
125 |
126 | Please ensure popups are not blocked, and JavaScript is enabled.
127 |
128 | ## Dependencies
129 |
130 | This sample is dependent on the following libraries/SDKs:
131 |
132 | ### Firebase
133 | - [firebase-app.js v4.0.0+](https://firebase.google.com/docs/web/setup#add_firebase_to_your_app)
134 | - [firebase-auth.js v4.0.0+](https://firebase.google.com/docs/web/setup#add_firebase_to_your_app)
135 | - [firebase-database.js v4.0.0+](https://firebase.google.com/docs/web/setup#add_firebase_to_your_app)
136 |
137 | ### Firebase Continue
138 | - [Firebase Continue for Chrome Extensions v0.1.0+](../../chrome-extensions)
139 |
140 | ### Material Design Lite
141 | - [Material Design Lite v1.3.0+](https://getmdl.io/)
142 |
143 | ## Disclaimer
144 |
145 | The focus of this sample is to demonstrate Firebase Continue usage in a
146 | somewhat realistic scenario. This sample can also act as a simple model of how
147 | to use Firebase in a Chrome extension.
148 |
149 | The focus is *not*, however, to have a perfect user interface or user
150 | experience. Please keep that in mind when trying out this sample.
151 |
--------------------------------------------------------------------------------
/samples/ios/Continote/Continote.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/samples/ios/Continote/Continote.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/samples/ios/Continote/Continote/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2017 Google Inc.
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License");
5 | // you may not use this file except in compliance with the License.
6 | // You may obtain a copy of the License at
7 | //
8 | // http://www.apache.org/licenses/LICENSE-2.0
9 | //
10 | // Unless required by applicable law or agreed to in writing, software
11 | // distributed under the License is distributed on an "AS IS" BASIS,
12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | // See the License for the specific language governing permissions and
14 | // limitations under the License.
15 | //
16 |
17 | import UIKit
18 | import Firebase
19 | import FirebaseAuth
20 | import FirebaseAuthUI
21 |
22 | @UIApplicationMain
23 | class AppDelegate: UIResponder, UIApplicationDelegate {
24 |
25 | var window: UIWindow?
26 |
27 | func application(_ application: UIApplication,
28 | didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
29 |
30 | // Set up Firebase
31 | FirebaseApp.configure()
32 |
33 | return true
34 | }
35 |
36 | @available(iOS 9.0, *)
37 | func application(_ app: UIApplication, open url: URL,
38 | options: [UIApplicationOpenURLOptionsKey: Any]) -> Bool {
39 | let sourceApplication = options[UIApplicationOpenURLOptionsKey.sourceApplication] as! String?
40 | return handleOpenUrl(url, sourceApplication: sourceApplication)
41 | }
42 |
43 | @available(iOS 8.0, *)
44 | func application(_ application: UIApplication, open url: URL,
45 | sourceApplication: String?, annotation: Any) -> Bool {
46 | return handleOpenUrl(url, sourceApplication: sourceApplication)
47 | }
48 |
49 | /**
50 | Handles opening a URL to complete the sign in process.
51 |
52 | - Parameter url: This is passed to FirebaseUI to complete the sign in process.
53 | - Parameter sourceApplication: This is passed to FirebaseUI to complete the sign in process.
54 | - Returns: true iff FirebaseAuthUI handled the url, false otherwise.
55 | */
56 | func handleOpenUrl(_ url: URL, sourceApplication: String?) -> Bool {
57 | // This is needed to complete the sign in process.
58 | if FUIAuth.defaultAuthUI()?.handleOpen(url, sourceApplication: sourceApplication) ?? false {
59 | return true
60 | }
61 |
62 | return false
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/samples/ios/Continote/Continote/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "filename" : "Icon-60@2x.png",
37 | "scale" : "2x"
38 | },
39 | {
40 | "idiom" : "iphone",
41 | "size" : "60x60",
42 | "filename" : "Icon-60@3x.png",
43 | "scale" : "3x"
44 | },
45 | {
46 | "idiom" : "ipad",
47 | "size" : "20x20",
48 | "scale" : "1x"
49 | },
50 | {
51 | "idiom" : "ipad",
52 | "size" : "20x20",
53 | "scale" : "2x"
54 | },
55 | {
56 | "idiom" : "ipad",
57 | "size" : "29x29",
58 | "scale" : "1x"
59 | },
60 | {
61 | "idiom" : "ipad",
62 | "size" : "29x29",
63 | "scale" : "2x"
64 | },
65 | {
66 | "idiom" : "ipad",
67 | "size" : "40x40",
68 | "scale" : "1x"
69 | },
70 | {
71 | "idiom" : "ipad",
72 | "size" : "40x40",
73 | "scale" : "2x"
74 | },
75 | {
76 | "idiom" : "ipad",
77 | "size" : "76x76",
78 | "filename" : "Icon-76@1x.png",
79 | "scale" : "1x"
80 | },
81 | {
82 | "idiom" : "ipad",
83 | "size" : "76x76",
84 | "filename" : "Icon-76@2x.png",
85 | "scale" : "2x"
86 | },
87 | {
88 | "idiom" : "ipad",
89 | "size" : "83.5x83.5",
90 | "filename" : "Icon-83.5@2x.png",
91 | "scale" : "2x"
92 | }
93 | ],
94 | "info" : {
95 | "version" : 1,
96 | "author" : "xcode"
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/samples/ios/Continote/Continote/Assets.xcassets/AppIcon.appiconset/Icon-60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FirebaseExtended/firebase-continue/b8c94cad16a80efba152f20a0f652e38050611f9/samples/ios/Continote/Continote/Assets.xcassets/AppIcon.appiconset/Icon-60@2x.png
--------------------------------------------------------------------------------
/samples/ios/Continote/Continote/Assets.xcassets/AppIcon.appiconset/Icon-60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FirebaseExtended/firebase-continue/b8c94cad16a80efba152f20a0f652e38050611f9/samples/ios/Continote/Continote/Assets.xcassets/AppIcon.appiconset/Icon-60@3x.png
--------------------------------------------------------------------------------
/samples/ios/Continote/Continote/Assets.xcassets/AppIcon.appiconset/Icon-76@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FirebaseExtended/firebase-continue/b8c94cad16a80efba152f20a0f652e38050611f9/samples/ios/Continote/Continote/Assets.xcassets/AppIcon.appiconset/Icon-76@1x.png
--------------------------------------------------------------------------------
/samples/ios/Continote/Continote/Assets.xcassets/AppIcon.appiconset/Icon-76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FirebaseExtended/firebase-continue/b8c94cad16a80efba152f20a0f652e38050611f9/samples/ios/Continote/Continote/Assets.xcassets/AppIcon.appiconset/Icon-76@2x.png
--------------------------------------------------------------------------------
/samples/ios/Continote/Continote/Assets.xcassets/AppIcon.appiconset/Icon-83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FirebaseExtended/firebase-continue/b8c94cad16a80efba152f20a0f652e38050611f9/samples/ios/Continote/Continote/Assets.xcassets/AppIcon.appiconset/Icon-83.5@2x.png
--------------------------------------------------------------------------------
/samples/ios/Continote/Continote/Assets.xcassets/LaunchImage.launchimage/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "orientation" : "portrait",
5 | "idiom" : "ipad",
6 | "extent" : "full-screen",
7 | "minimum-system-version" : "7.0",
8 | "scale" : "1x"
9 | },
10 | {
11 | "orientation" : "landscape",
12 | "idiom" : "ipad",
13 | "extent" : "full-screen",
14 | "minimum-system-version" : "7.0",
15 | "scale" : "1x"
16 | },
17 | {
18 | "orientation" : "portrait",
19 | "idiom" : "ipad",
20 | "extent" : "full-screen",
21 | "minimum-system-version" : "7.0",
22 | "scale" : "2x"
23 | },
24 | {
25 | "orientation" : "landscape",
26 | "idiom" : "ipad",
27 | "extent" : "full-screen",
28 | "minimum-system-version" : "7.0",
29 | "scale" : "2x"
30 | }
31 | ],
32 | "info" : {
33 | "version" : 1,
34 | "author" : "xcode"
35 | }
36 | }
--------------------------------------------------------------------------------
/samples/ios/Continote/Continote/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/samples/ios/Continote/Continote/BaseViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2017 Google Inc.
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License");
5 | // you may not use this file except in compliance with the License.
6 | // You may obtain a copy of the License at
7 | //
8 | // http://www.apache.org/licenses/LICENSE-2.0
9 | //
10 | // Unless required by applicable law or agreed to in writing, software
11 | // distributed under the License is distributed on an "AS IS" BASIS,
12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | // See the License for the specific language governing permissions and
14 | // limitations under the License.
15 | //
16 |
17 | import UIKit
18 | import Firebase
19 | import MaterialComponents.MaterialAppBar
20 |
21 | /**
22 | The abstract UIViewController which all other ViewControllers in this app must subclass.
23 |
24 | It sets up various common UI elements (such as the top AppBar for navigation and title purposes),
25 | and listens for authentication state changes to pass along to subclasses.
26 | */
27 | class BaseViewController: UIViewController {
28 |
29 | // Firebase related
30 | private lazy var auth: Auth = { Auth.auth() }()
31 | private var authStateDidChangeListenerHandle: AuthStateDidChangeListenerHandle?
32 |
33 | // AppBar for navigation and title purposes. This replaces the standard UINavigationController's
34 | // navigation bar.
35 | private let appBar = MDCAppBar()
36 |
37 | override func viewDidLoad() {
38 | super.viewDidLoad()
39 |
40 | // Set up this screen's AppBar.
41 | addChildViewController(appBar.headerViewController)
42 | appBar.addSubviewsToParent()
43 | appBar.applyAppTheme()
44 | }
45 |
46 | override func viewWillAppear(_ animated: Bool) {
47 | super.viewWillAppear(animated)
48 |
49 | // Hide the UINavigationController's NavigationBar since we are using a Material Components
50 | // AppBar.
51 | // See: https://material.io/components/ios/catalog/flexible-headers/#interacting-with-uinavigationcontroller
52 | navigationController?.setNavigationBarHidden(true, animated: animated)
53 |
54 | // Add the authentication state handler to get current state as well as any future changes.
55 | authStateDidChangeListenerHandle =
56 | auth.addStateDidChangeListener(handleAuthStateDidChange(auth:user:))
57 | }
58 |
59 | override func viewWillDisappear(_ animated: Bool) {
60 | super.viewWillDisappear(animated)
61 |
62 | // Remove the authentication state handler.
63 | if let handle = authStateDidChangeListenerHandle {
64 | auth.removeStateDidChangeListener(handle)
65 | authStateDidChangeListenerHandle = nil
66 | }
67 | }
68 |
69 | override func viewWillLayoutSubviews() {
70 | super.viewDidLayoutSubviews()
71 |
72 | // Ensure the main screen UI falls below the top AppBar.
73 | // See: https://material.io/components/ios/catalog/flexible-headers/
74 | appBar.headerViewController.updateTopLayoutGuide()
75 | }
76 |
77 | /**
78 | Handles when the user signs in.
79 |
80 | Override in a subclass to react to this event.
81 |
82 | - Parameter user: The user who is now signed in.
83 | */
84 | func handleUserSignedIn(_ user: User) {}
85 |
86 | /**
87 | Handles when the user signs out.
88 |
89 | Override in a subclass to react to this event.
90 | */
91 | func handleUserSignedOut() {}
92 |
93 | /**
94 | Determines if the user is currently signed in.
95 |
96 | - Returns: true iff the current user is signed into this app, false otherwise.
97 | */
98 | func currentUserIsSignedIn() -> Bool {
99 | return auth.currentUser != nil
100 | }
101 |
102 | /**
103 | Handles when the user's Auth state changes.
104 |
105 | Firebase is provided this method as a callback for when the user signs in or out.
106 |
107 | It is also invoked right away by Firebase with the initial Auth state when the handler is
108 | registered with Firebase.
109 |
110 | See: https://firebase.google.com/docs/reference/ios/firebaseauth/api/reference/Classes/FIRAuth#-addauthstatedidchangelistener
111 |
112 | - Parameter auth: The Auth instance which called this listener.
113 | - Parameter user: The user who is now signed in, or nil if no user is signed in.
114 | */
115 | func handleAuthStateDidChange(auth: Auth, user: User?) {
116 | if let user = user {
117 | // The user IS signed in.
118 | handleUserSignedIn(user)
119 | } else {
120 | // The user is NOT signed in.
121 | handleUserSignedOut()
122 | }
123 | }
124 | }
125 |
--------------------------------------------------------------------------------
/samples/ios/Continote/Continote/Continote-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2017 Google Inc.
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License");
5 | // you may not use this file except in compliance with the License.
6 | // You may obtain a copy of the License at
7 | //
8 | // http://www.apache.org/licenses/LICENSE-2.0
9 | //
10 | // Unless required by applicable law or agreed to in writing, software
11 | // distributed under the License is distributed on an "AS IS" BASIS,
12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | // See the License for the specific language governing permissions and
14 | // limitations under the License.
15 | //
16 |
17 | #import "FCNContinue.h"
18 |
--------------------------------------------------------------------------------
/samples/ios/Continote/Continote/MainViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2017 Google Inc.
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License");
5 | // you may not use this file except in compliance with the License.
6 | // You may obtain a copy of the License at
7 | //
8 | // http://www.apache.org/licenses/LICENSE-2.0
9 | //
10 | // Unless required by applicable law or agreed to in writing, software
11 | // distributed under the License is distributed on an "AS IS" BASIS,
12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | // See the License for the specific language governing permissions and
14 | // limitations under the License.
15 | //
16 |
17 | import UIKit
18 | import FirebaseAuthUI
19 | import FirebaseFacebookAuthUI
20 | import FirebaseGoogleAuthUI
21 | import MaterialComponents.MaterialButtons
22 | import MaterialComponents.MaterialSnackbar
23 |
24 | /**
25 | The ViewController that is initially pushed onto this app's UINavigationController.
26 |
27 | It presents the user with an initial screen to either sign in and then navigate to other screens,
28 | or sign out.
29 | */
30 | class MainViewController: BaseViewController {
31 |
32 | // FirebaseUI related
33 | private lazy var authUI: FUIAuth = {
34 | // Set up FirebaseUI authentication.
35 | let customizedAuthUI: FUIAuth = FUIAuth.defaultAuthUI()!
36 | customizedAuthUI.providers = Constants.Auth.providers
37 | customizedAuthUI.isSignInWithEmailHidden = true
38 | return customizedAuthUI
39 | }()
40 |
41 | // UI outlets
42 | @IBOutlet var authLabel: UILabel!
43 | @IBOutlet var authButton: MDCRaisedButton!
44 | @IBOutlet var myNotesButton: MDCRaisedButton!
45 |
46 | override func viewDidLoad() {
47 | super.viewDidLoad()
48 |
49 | // Set up this screen's AppBar title.
50 | title = Constants.appName
51 |
52 | // Style all labels.
53 | authLabel.applyAppTheme(for: .normalText)
54 |
55 | // Style all buttons.
56 | authButton.applyAppTheme()
57 | myNotesButton.applyAppTheme()
58 | }
59 |
60 | override func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool {
61 | guard let destination = Constants.Segue(rawValue: identifier) else { return false }
62 |
63 | if destination == .myNotes {
64 | // The user should only be able to go to the notes screen if they are signed in.
65 | return currentUserIsSignedIn()
66 | }
67 |
68 | return false
69 | }
70 |
71 | override func handleUserSignedIn(_ user: User) {
72 | super.handleUserSignedIn(user)
73 |
74 | // Update the UI to reflect the user now being signed in.
75 | let name:String = user.displayName!
76 | let email:String = user.email!
77 | authLabel.text = String(format: Constants.Text.welcomeMessage, name, email)
78 | authButton.setTitle(Constants.Text.signOutButtonTitle, for: .normal)
79 | myNotesButton.isHidden = false
80 | }
81 |
82 | override func handleUserSignedOut() {
83 | super.handleUserSignedOut()
84 |
85 | // Update the UI to reflect the user now being signed out.
86 | authLabel.text = Constants.Text.signInMessage
87 | authButton.setTitle(Constants.Text.signInButtonTitle, for: .normal)
88 | myNotesButton.isHidden = true
89 | }
90 |
91 | /**
92 | Presents the sign in screen to the user, if they are currently signed out.
93 | */
94 | func presentSignInScreen() {
95 | guard !currentUserIsSignedIn() else { return }
96 |
97 | // Present the sign in screen.
98 | present(authUI.authViewController(), animated: true)
99 | }
100 |
101 | /**
102 | Signs the user out, if they are currently signed in.
103 | */
104 | func signUserOut() {
105 | guard currentUserIsSignedIn() else { return }
106 |
107 | do {
108 | // Try to sign the user out.
109 | try authUI.signOut()
110 | } catch {
111 | MDCSnackbarManager.show(Constants.Text.ErrorMessage.couldNotSignOut)
112 | }
113 | }
114 |
115 | /**
116 | Handles when the user taps the auth (i.e. "Sign In"/"Sign Out") button.
117 |
118 | - Parameter sender: The object that called this action. This should only be the authButton.
119 | */
120 | @IBAction func authButtonAction(_ sender: Any) {
121 | if !currentUserIsSignedIn() {
122 | // The user is NOT signed in, so they want to sign in.
123 | presentSignInScreen()
124 | } else {
125 | // The user IS signed in, so they want to sign out.
126 | signUserOut()
127 | }
128 | }
129 | }
130 |
131 | /**
132 | These local constants are organized as a private extension to the global Constants struct
133 | for clarity and a cleaner namespace.
134 | */
135 | private extension Constants {
136 | struct Auth {
137 | // These are the authentication methods this app allows.
138 | static let providers: [FUIAuthProvider] = [FUIGoogleAuth(), FUIFacebookAuth()]
139 | }
140 |
141 | struct Text {
142 | static let signInMessage: String = "Please sign in below to use \(appName)."
143 | static let welcomeMessage: String = "Hello %@!\nYou are currently signed in as %@"
144 |
145 | static let signInButtonTitle: String = "Sign In"
146 | static let signOutButtonTitle: String = "Sign Out"
147 |
148 | struct ErrorMessage {
149 | static let couldNotSignOut: String = "Could not sign out. Please try again."
150 | }
151 | }
152 |
153 | // These segue identifiers must match the identifiers defined in the Main storyboard.
154 | enum Segue: String {
155 | case myNotes = "myNotes"
156 | }
157 | }
158 |
--------------------------------------------------------------------------------
/samples/ios/Continote/Continote/MyNotesTableViewCell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2017 Google Inc.
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License");
5 | // you may not use this file except in compliance with the License.
6 | // You may obtain a copy of the License at
7 | //
8 | // http://www.apache.org/licenses/LICENSE-2.0
9 | //
10 | // Unless required by applicable law or agreed to in writing, software
11 | // distributed under the License is distributed on an "AS IS" BASIS,
12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | // See the License for the specific language governing permissions and
14 | // limitations under the License.
15 | //
16 |
17 | import UIKit
18 |
19 | /**
20 | The TableView within MyNotesViewController is filled with these cells (one per Note).
21 | */
22 | class MyNotesTableViewCell: UITableViewCell {
23 |
24 | // The key from the Firebase Realtime Database for the Note this cell represents.
25 | // This is passed to the EditNoteViewController.
26 | var noteKey: String?
27 |
28 | // The Note this cell represents.
29 | var note: Note? {
30 | didSet {
31 | // Populate this cell with the values from the Note.
32 | titleLabel.setText(to: note?.title,
33 | withPlaceholder: "No Title",
34 | using: Constants.Theme.LabelKind.titleText.getFont())
35 | contentLabel.setText(to: note?.content,
36 | withPlaceholder: "No Content",
37 | using: Constants.Theme.LabelKind.normalText.getFont())
38 | }
39 | }
40 |
41 | // UI outlets
42 | @IBOutlet var titleLabel: UILabel!
43 | @IBOutlet var contentLabel: UILabel!
44 |
45 | override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
46 | super.init(style: style, reuseIdentifier: reuseIdentifier)
47 |
48 | // Style all labels.
49 | titleLabel.applyAppTheme(for: .titleText)
50 | contentLabel.applyAppTheme(for: .normalText)
51 | }
52 |
53 | required init?(coder aDecoder: NSCoder) {
54 | super.init(coder: aDecoder)
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/samples/ios/Continote/Continote/MyNotesTableViewDataSource.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2017 Google Inc.
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License");
5 | // you may not use this file except in compliance with the License.
6 | // You may obtain a copy of the License at
7 | //
8 | // http://www.apache.org/licenses/LICENSE-2.0
9 | //
10 | // Unless required by applicable law or agreed to in writing, software
11 | // distributed under the License is distributed on an "AS IS" BASIS,
12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | // See the License for the specific language governing permissions and
14 | // limitations under the License.
15 | //
16 |
17 | import UIKit
18 | import FirebaseDatabase
19 | import FirebaseDatabaseUI
20 | import MaterialComponents.MaterialSnackbar
21 |
22 | /**
23 | The data source used for the TableView in MyNotesViewController.
24 |
25 | We need to override FUITableViewDataSource in order to allow the user to edit
26 | (and then subsequently delete) rows (i.e. Notes) within the table.
27 | */
28 | class MyNotesTableViewDataSource: FUITableViewDataSource {
29 |
30 | override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
31 | // Allow the user to edit any row in the table.
32 | return true
33 | }
34 |
35 | override func tableView(_ tableView: UITableView,
36 | commit editingStyle: UITableViewCellEditingStyle,
37 | forRowAt indexPath: IndexPath) {
38 | guard editingStyle == .delete else { return }
39 |
40 | // Attempt to delete the corresponding Note from the Firebase Realtime Database.
41 | if (UInt(indexPath.row) < count) {
42 | snapshot(at: indexPath.row).ref.removeValue { (error, ref) in
43 | guard error == nil else {
44 | MDCSnackbarManager.show(Constants.AppError.couldNotDeleteNote.rawValue)
45 | return
46 | }
47 | }
48 | }
49 | }
50 | }
51 |
52 | /**
53 | These local constants are organized as a private extension to the global Constants struct
54 | for clarity and a cleaner namespace.
55 | */
56 | private extension Constants {
57 | enum AppError: String, Error {
58 | case couldNotDeleteNote = "Could not delete note. Please try again."
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/samples/ios/Continote/Continote/MyNotesViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2017 Google Inc.
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License");
5 | // you may not use this file except in compliance with the License.
6 | // You may obtain a copy of the License at
7 | //
8 | // http://www.apache.org/licenses/LICENSE-2.0
9 | //
10 | // Unless required by applicable law or agreed to in writing, software
11 | // distributed under the License is distributed on an "AS IS" BASIS,
12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | // See the License for the specific language governing permissions and
14 | // limitations under the License.
15 | //
16 |
17 | import UIKit
18 | import Firebase
19 | import FirebaseDatabaseUI
20 | import MaterialComponents.MaterialButtons
21 |
22 | /**
23 | The ViewController that presents the user with a table of their Notes in Continote.
24 |
25 | From here the user can add, delete, or open to edit Notes.
26 | */
27 | class MyNotesViewController: BaseViewController {
28 |
29 | // Firebase Realtime Database reference for the current user's Notes within Continote.
30 | private var notesRef: DatabaseReference?
31 |
32 | // The data source to populate the TableView of Notes for the current user.
33 | private var dataSource: MyNotesTableViewDataSource?
34 |
35 | // UI outlets
36 | @IBOutlet var tableView: UITableView!
37 | @IBOutlet var newNoteButton: MDCRaisedButton!
38 |
39 | override func viewDidLoad() {
40 | super.viewDidLoad()
41 |
42 | // Set up this screen's AppBar title.
43 | title = Constants.Text.screenTitle
44 |
45 | // Style all buttons.
46 | newNoteButton.applyAppTheme()
47 | }
48 |
49 | override func viewWillDisappear(_ animated: Bool) {
50 | super.viewWillDisappear(animated)
51 |
52 | // Remove all bindings and database observers.
53 | dataSource?.unbind()
54 | dataSource = nil
55 | notesRef?.removeAllObservers()
56 | notesRef = nil
57 | }
58 |
59 | override func viewDidAppear(_ animated: Bool) {
60 | super.viewDidAppear(animated)
61 |
62 | tableView.flashScrollIndicators()
63 | }
64 |
65 | override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
66 | guard let identifierString = segue.identifier,
67 | let segueIdentifier = Constants.Segue(rawValue: identifierString),
68 | segueIdentifier == .editNote else { return }
69 |
70 | // We need to let the EditNoteViewController know which Note the user wishes to edit
71 | // before the segue can be performed.
72 | let editNoteViewController = segue.destination as! EditNoteViewController
73 |
74 | // Set the databaseKey based on the object passed in.
75 | if let cell = sender as? MyNotesTableViewCell {
76 | editNoteViewController.databaseKey = cell.noteKey
77 | } else if let key = sender as? String {
78 | editNoteViewController.databaseKey = key
79 | }
80 | }
81 |
82 | override func handleUserSignedIn(_ user: User) {
83 | super.handleUserSignedIn(user)
84 |
85 | // Set up our TableView up to sync with the Notes for the current user from the Firebase
86 | // Realtime Database.
87 | notesRef = Database.database().reference(withPath: "notes/\(user.uid)")
88 | dataSource = MyNotesTableViewDataSource(
89 | query: notesRef!,
90 | populateCell: { tableView, indexPath, snapshot in
91 | // Get the data for this Note, as gathered from the Firebase Realtime Database, and parse
92 | // it to create a Note struct for this cell.
93 | let noteKey:String = snapshot.key
94 | let note: Note? = Note(with: snapshot)
95 |
96 | // Get and then populate a cell in the TableView to use for this Note.
97 | let cell = tableView.dequeueReusableCell(withIdentifier: "MyNotesTableViewCell")
98 | as! MyNotesTableViewCell
99 | cell.noteKey = noteKey
100 | cell.note = note
101 |
102 | return cell
103 | })
104 |
105 | dataSource?.bind(to: tableView)
106 |
107 | // Finally, show this screen's UI since everything is ready.
108 | tableView.isHidden = false
109 | newNoteButton.isHidden = false
110 | }
111 |
112 | override func handleUserSignedOut() {
113 | super.handleUserSignedOut()
114 |
115 | // Hide this screen's UI since the user must be signed in to see any Notes.
116 | tableView.isHidden = true
117 | newNoteButton.isHidden = true
118 |
119 | // The user must be signed in to view this screen, so navigate away from it if the user is
120 | // signed out.
121 | navigationController?.popViewController(animated: true)
122 | }
123 |
124 | /**
125 | Handles when the user taps the newNoteButton.
126 |
127 | Adds a new Note to the Firebase Realtime Database for the current user,
128 | then opens that Note to allow the user to begin writing.
129 |
130 | - Parameter sender: The object that called this action. This should only be the newNoteButton.
131 | */
132 | @IBAction func newNoteButtonAction(_ sender: Any) {
133 | guard let notesRef = notesRef else { return }
134 |
135 | // Add a new, empty Note to the Firebase Realtime Database for the current user.
136 | let newNote: Note = Note(title: "", content: "")
137 | let newNoteRef: DatabaseReference = notesRef.childByAutoId()
138 | newNoteRef.setValue(newNote.firebaseData) { [weak self] (error, ref) -> Void in
139 | guard error == nil else {
140 | MDCSnackbarManager.show(Constants.AppError.couldNotCreateNewNote.rawValue)
141 | return
142 | }
143 |
144 | // Open the Edit Note screen with this Note.
145 | // We do this so that the user may immediately edit the Note, rather than
146 | // having to wait for the TableView to update from Firebase Realtime Database
147 | // events and then manually tap the cell for the Note.
148 | DispatchQueue.main.async {
149 | self?.performSegue(withIdentifier: Constants.Segue.editNote.rawValue, sender: ref.key)
150 | }
151 | }
152 | }
153 | }
154 |
155 | /**
156 | These local constants are organized as a private extension to the global Constants struct
157 | for clarity and a cleaner namespace.
158 | */
159 | private extension Constants {
160 | struct Text {
161 | static let screenTitle: String = "My Notes"
162 | }
163 |
164 | enum AppError: String, Error {
165 | case couldNotCreateNewNote = "Could not create a new note. Please try again."
166 | }
167 |
168 | // These segue identifiers must match the identifiers defined in the Main storyboard.
169 | enum Segue: String {
170 | case editNote = "editNote"
171 | }
172 | }
173 |
--------------------------------------------------------------------------------
/samples/ios/Continote/Continote/Note.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2017 Google Inc.
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License");
5 | // you may not use this file except in compliance with the License.
6 | // You may obtain a copy of the License at
7 | //
8 | // http://www.apache.org/licenses/LICENSE-2.0
9 | //
10 | // Unless required by applicable law or agreed to in writing, software
11 | // distributed under the License is distributed on an "AS IS" BASIS,
12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | // See the License for the specific language governing permissions and
14 | // limitations under the License.
15 | //
16 |
17 | import FirebaseDatabase
18 |
19 | /**
20 | A Note for the user within Continote.
21 | The schema of each Note is outlined in sample-database.rules.json within the web sample.
22 |
23 | Each Note is considered immutable on the client-side to simplify syncing with the database for
24 | this sample.
25 | */
26 | struct Note {
27 |
28 | // The title of this Note.
29 | let title: String
30 |
31 | // The main content of this Note.
32 | let content: String
33 |
34 | // The Firebase Realtime Database representation of this Note.
35 | // This could be used to add or set a Note value in the database.
36 | let firebaseData: [String : AnyObject]
37 |
38 | /**
39 | Initializes a Note with the provided values.
40 |
41 | - Parameter title: The title of the Note.
42 | - Parameter content: The main content of the Note.
43 | */
44 | init(title: String, content: String) {
45 | self.title = title
46 | self.content = content
47 | firebaseData = [
48 | "title": self.title as AnyObject,
49 | "content": self.content as AnyObject
50 | ]
51 | }
52 |
53 | /**
54 | Attempts to initialize a Note using values from the provided Firebase Realtime Database data
55 | snapshot. This could be more robust, but is sufficient for this sample app.
56 |
57 | - Parameter firebaseData: The Firebase data snapshot to attempt to convert into a Note.
58 | */
59 | init?(with firebaseData: DataSnapshot?) {
60 | guard let data = firebaseData,
61 | let value = data.value as? [String : AnyObject],
62 | let noteTitle = value["title"] as? String,
63 | let noteContent = value["content"] as? String else {
64 | return nil
65 | }
66 |
67 | self.init(title: noteTitle, content: noteContent)
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/samples/ios/Continote/Continote/Sample-Constants.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2017 Google Inc.
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License");
5 | // you may not use this file except in compliance with the License.
6 | // You may obtain a copy of the License at
7 | //
8 | // http://www.apache.org/licenses/LICENSE-2.0
9 | //
10 | // Unless required by applicable law or agreed to in writing, software
11 | // distributed under the License is distributed on an "AS IS" BASIS,
12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | // See the License for the specific language governing permissions and
14 | // limitations under the License.
15 | //
16 |
17 | import MaterialComponents.MaterialTypography
18 | import MaterialComponents.MDCColorScheme
19 |
20 | /**
21 | These constants are organized as part of a struct for clarity and a cleaner namespace.
22 |
23 | The constants predefined below are relevant to more than one screen within the app.
24 | For local constants, use a private extension within the file you need those extra constants.
25 | See the use of "private extension Constants" in MainViewController.swift for an example.
26 | */
27 | struct Constants {
28 | static let appName: String = "Continote"
29 |
30 | // FirebaseContinue usage related.
31 | struct FirebaseContinue {
32 | static let applicationName: String = "continote"
33 | static let urlToEditNoteWithKey: String =
34 | "[TODO: YOUR-FIREBASE-HOSTING-URL-FOR-CONTINOTE-WEB-HERE]/edit-note.html?noteKey=%@"
35 | }
36 |
37 | // UI appearance related constants.
38 | struct Theme {
39 |
40 | // The color scheme we will apply to Material Components to mimic the look of Firebase.
41 | static let colorScheme: MDCColorScheme & NSObjectProtocol =
42 | MDCBasicColorScheme.init(
43 | primaryColor: UIColor(red: 1.0, green: 0.76, blue: 0.05, alpha: 1.0),
44 | secondaryColor: UIColor(red: 1.0, green: 0.6, blue: 0, alpha: 1.0))
45 |
46 | struct Button {
47 | // The elevation for buttons to give a raised look.
48 | static let elevation: CGFloat = 4;
49 | }
50 |
51 | // All text-based inputs (i.e. UITextField and UITextView).
52 | struct TextInput {
53 | static let borderColor: CGColor =
54 | UIColor(red: 0.76, green: 0.76, blue: 0.76, alpha: 0.5).cgColor
55 | static let borderWidth: CGFloat = 1
56 | static let borderCornerRadius: CGFloat = 2
57 | }
58 |
59 | enum LabelKind {
60 |
61 | // Labels with text we wish to appear normal/standard (such as longer text content).
62 | case normalText
63 |
64 | // Labels with text we wish to appear as a title.
65 | case titleText
66 |
67 | /**
68 | - Returns: The font to use for this kind of label.
69 | */
70 | func getFont() -> UIFont {
71 | switch self {
72 | case .normalText:
73 | return MDCTypography.subheadFont()
74 | case .titleText:
75 | return MDCTypography.titleFont()
76 | }
77 | }
78 |
79 | /**
80 | - Returns: The alpha to use for this kind of label.
81 | */
82 | func getAlpha() -> CGFloat {
83 | switch self {
84 | case .normalText:
85 | return MDCTypography.subheadFontOpacity()
86 | case .titleText:
87 | return MDCTypography.titleFontOpacity()
88 | }
89 | }
90 | }
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/samples/ios/Continote/Continote/Utils.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2017 Google Inc.
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License");
5 | // you may not use this file except in compliance with the License.
6 | // You may obtain a copy of the License at
7 | //
8 | // http://www.apache.org/licenses/LICENSE-2.0
9 | //
10 | // Unless required by applicable law or agreed to in writing, software
11 | // distributed under the License is distributed on an "AS IS" BASIS,
12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | // See the License for the specific language governing permissions and
14 | // limitations under the License.
15 | //
16 |
17 | import MaterialComponents.MaterialAppBar
18 | import MaterialComponents.MaterialButtons
19 | import MaterialComponents.MaterialSnackbar
20 | import MaterialComponents.MaterialTextFields
21 | import MaterialComponents.MDCAppBarColorThemer
22 | import MaterialComponents.MDCButtonColorThemer
23 | import MaterialComponents.MDCTypography
24 |
25 | /**
26 | This file provides some simple utility functions for use throughout the app.
27 | */
28 |
29 | extension MDCAppBar {
30 | /**
31 | Applies a standardized visual style to this AppBar.
32 | */
33 | func applyAppTheme() {
34 | MDCAppBarColorThemer.apply(Constants.Theme.colorScheme, to: self)
35 | }
36 | }
37 |
38 | extension MDCRaisedButton {
39 | /**
40 | Applies a standardized visual style to this button.
41 | */
42 | func applyAppTheme() {
43 | setElevation(Constants.Theme.Button.elevation, for: .normal)
44 | MDCButtonColorThemer.apply(Constants.Theme.colorScheme, to: self)
45 | }
46 | }
47 |
48 | extension UILabel {
49 | /**
50 | Applies a standardized visual style to this label of a certain kind.
51 |
52 | - Parameter labelKind: The kind of label to appear as.
53 | */
54 | func applyAppTheme(for labelKind: Constants.Theme.LabelKind) {
55 | font = labelKind.getFont()
56 | alpha = labelKind.getAlpha()
57 | }
58 |
59 | /**
60 | Sets this label's text to the provided value, or the provided placeholder if the value is
61 | nil or empty.
62 |
63 | If the text is set to the provided value, the desiredFont will be applied to the label.
64 | Otherwise, if the placeholder is used, an italicized version of the desiredFont will be applied.
65 |
66 | - Parameter value: The value to set the text to.
67 | - Parameter placeholder: The placeholder text to use if the value above is nil or empty.
68 | - Parameter desiredFont: The font to use if the text is set to the provided value.
69 | */
70 | func setText(to value: String?, withPlaceholder placeholder: String, using desiredFont: UIFont) {
71 | if !(value ?? "").isEmpty {
72 | text = value;
73 | font = desiredFont
74 | } else {
75 | text = placeholder;
76 | font = MDCTypography.italicFont(from: desiredFont)
77 | }
78 | }
79 | }
80 |
81 | extension MDCTextField {
82 | /**
83 | Applies a standardized visual style to this MDCTextField.
84 | */
85 | func applyAppTheme() {
86 | font = Constants.Theme.LabelKind.titleText.getFont()
87 | }
88 | }
89 |
90 | extension MDCMultilineTextField {
91 | /**
92 | Applies a standardized visual style to this MDCMultilineTextField.
93 | */
94 | func applyAppTheme() {
95 | font = Constants.Theme.LabelKind.normalText.getFont()
96 | }
97 | }
98 |
99 | extension MDCSnackbarManager {
100 | /**
101 | Shows the provided text in a snackbar message.
102 |
103 | See: https://material.io/components/ios/catalog/snackbars/
104 |
105 | - Parameter text: The text to show.
106 | */
107 | static func show(_ text: String) {
108 | MDCSnackbarManager.show(MDCSnackbarMessage(text: text))
109 | }
110 | }
111 |
--------------------------------------------------------------------------------
/samples/ios/Continote/Continote/sample-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | FacebookAppID
6 | [TODO: YOUR-FACEBOOK-APP-ID-HERE]
7 | FacebookDisplayName
8 | [TODO: YOUR-FACEBOOK-APP-NAME-HERE]
9 | LSApplicationQueriesSchemes
10 |
11 | fbauth2
12 |
13 | CFBundleDevelopmentRegion
14 | en
15 | CFBundleDisplayName
16 | Continote
17 | CFBundleExecutable
18 | $(EXECUTABLE_NAME)
19 | CFBundleIdentifier
20 | $(PRODUCT_BUNDLE_IDENTIFIER)
21 | CFBundleInfoDictionaryVersion
22 | 6.0
23 | CFBundleName
24 | $(PRODUCT_NAME)
25 | CFBundlePackageType
26 | APPL
27 | CFBundleShortVersionString
28 | 1.0
29 | CFBundleURLTypes
30 |
31 |
32 | CFBundleTypeRole
33 | Editor
34 | CFBundleURLSchemes
35 |
36 | [TODO: YOUR-GOOGLESERVICE-INFO.PLIST-RESERVED_CLIENT_ID-HERE]
37 |
38 |
39 |
40 | CFBundleTypeRole
41 | Editor
42 | CFBundleURLSchemes
43 |
44 | fb[TODO: YOUR-FACEBOOK-APP-ID-HERE]
45 |
46 |
47 |
48 | CFBundleVersion
49 | 1
50 | LSRequiresIPhoneOS
51 |
52 | UILaunchStoryboardName
53 | LaunchScreen
54 | UIMainStoryboardFile
55 | Main
56 | UIRequiredDeviceCapabilities
57 |
58 | armv7
59 |
60 | UISupportedInterfaceOrientations
61 |
62 | UIInterfaceOrientationPortrait
63 |
64 | UISupportedInterfaceOrientations~ipad
65 |
66 | UIInterfaceOrientationPortrait
67 | UIInterfaceOrientationPortraitUpsideDown
68 | UIInterfaceOrientationLandscapeLeft
69 | UIInterfaceOrientationLandscapeRight
70 |
71 |
72 |
73 |
--------------------------------------------------------------------------------
/samples/ios/Continote/Podfile:
--------------------------------------------------------------------------------
1 | platform :ios, '8.0'
2 |
3 | target 'Continote' do
4 | use_frameworks!
5 |
6 | # Firebase (https://github.com/firebase/firebase-ios-sdk)
7 | pod 'Firebase/Auth', '~> 4.0'
8 | pod 'Firebase/Database', '~> 4.0'
9 |
10 | # FirebaseUI (https://github.com/firebase/FirebaseUI-iOS)
11 | pod 'FirebaseUI/Auth', '~> 4.0'
12 | pod 'FirebaseUI/Database', '~> 4.0'
13 | pod 'FirebaseUI/Google', '~> 4.0'
14 | pod 'FirebaseUI/Facebook', '~> 4.0'
15 |
16 | # Material Components (https://github.com/material-components/material-components-ios/)
17 | pod 'MaterialComponents/AppBar', '~> 31.0'
18 | pod 'MaterialComponents/AppBar/ColorThemer', '~> 31.0'
19 | pod 'MaterialComponents/Buttons', '~> 31.0'
20 | pod 'MaterialComponents/Buttons/ColorThemer', '~> 31.0'
21 | pod 'MaterialComponents/Snackbar', '~> 31.0'
22 | pod 'MaterialComponents/TextFields', '~> 31.0'
23 | pod 'MaterialComponents/Typography', '~> 31.0'
24 |
25 | end
26 |
--------------------------------------------------------------------------------
/samples/web/Continote/firebase.json:
--------------------------------------------------------------------------------
1 | {
2 | "database": {
3 | "rules": "database.rules.json"
4 | },
5 | "hosting": {
6 | "public": "public"
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/samples/web/Continote/public/404.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 | Continote - Firebase Continue Sample - 404 Page Not Found
27 |
28 |
29 |
31 |
33 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 | Continote —
53 | Firebase Continue Sample — 404 Page Not Found
54 |
55 |
56 |
57 |
58 |
59 |
60 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 | 404 Page Not Found
79 |
80 |
81 |
82 |
83 | The page you tried to visit was not found.
84 |
85 |
86 | Navigate back Home at the top of this page and try again.
87 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
--------------------------------------------------------------------------------
/samples/web/Continote/public/scripts/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2017 Google Inc. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a
6 | * copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations
14 | * under the License.
15 | */
16 |
17 | /**
18 | * This script is loaded and running whenever the index.html page is open.
19 | */
20 | (function() {
21 | 'use strict';
22 |
23 | /**
24 | * AuthHelper instance to simplify Firebase Auth usage.
25 | *
26 | * @type {?AuthHelper}
27 | */
28 | var authHelper_ = null;
29 |
30 | /**
31 | * Various UI elements which will be manipulated through the lifecycle of
32 | * this page. These are organized as part of an object for clarity and a
33 | * cleaner namespace.
34 | *
35 | * @type {!Object}
36 | * @const
37 | */
38 | var pageUi_ = {
39 | userDisplayName: null,
40 | userEmail: null,
41 | signOutButton: null
42 | };
43 |
44 | /**
45 | * Handles when the user signs in.
46 | *
47 | * See auth-helper.js for more details.
48 | *
49 | * @type {!UserSignedInCallback}
50 | * @const
51 | */
52 | var handleUserSignedIn_ = function(user) {
53 | // Set up the UI for signed in users.
54 | pageUi_.userDisplayName.textContent = user.displayName;
55 | pageUi_.userEmail.textContent = user.email;
56 | Utils.enableButtonAndAddClickListener(
57 | pageUi_.signOutButton, handleSignOutButtonClicked_);
58 | };
59 |
60 | /**
61 | * Handles when the user signs out.
62 | *
63 | * See auth-helper.js for more details.
64 | *
65 | * @type {!UserSignedOutCallback}
66 | * @const
67 | */
68 | var handleUserSignedOut_ = function() {
69 | // Tear down the UI for signed in users.
70 | Utils.disableButtonAndRemoveClickListener(
71 | pageUi_.signOutButton, handleSignOutButtonClicked_);
72 | };
73 |
74 | /**
75 | * Handles when the sign out button is clicked.
76 | *
77 | * Signs the user out, if they are signed in.
78 | *
79 | * @type {!ClickEventListener}
80 | * @const
81 | */
82 | var handleSignOutButtonClicked_ = function(event) {
83 | event.preventDefault();
84 |
85 | // Since the click event listener is only on the sign out button when the
86 | // user is signed in, we can reasonably assume the user is signed in.
87 | // However, signing out will fail if the user is already signed out,
88 | // so we need to handle that case in the catch function
89 | // below - just in case.
90 | authHelper_.signOut().catch(function(error) {
91 | switch (error) {
92 | case authHelper_.errorMessages.userAlreadySignedOut:
93 | // Do nothing, as the user is already signed out.
94 | break;
95 |
96 | default:
97 | console.error("Error during sign out: " + error);
98 | }
99 | });
100 | };
101 |
102 | /**
103 | * Initializes this page.
104 | *
105 | * This is the main entry point of this page's script.
106 | *
107 | * @function
108 | * @const
109 | */
110 | var init_ = function() {
111 | // Hold references to various UI elements for later manipulation.
112 | pageUi_.userDisplayName = document.getElementById("user-display-name");
113 | pageUi_.userEmail = document.getElementById("user-email");
114 | pageUi_.signOutButton = document.getElementById("sign-out-button");
115 |
116 | // Now that the page is ready, set up the Firebase Auth helper to listen
117 | // for sign in state changes, and to start FirebaseUI for a sign in UI
118 | // when the user is signed out.
119 | authHelper_ = new AuthHelper(handleUserSignedIn_, handleUserSignedOut_);
120 | };
121 |
122 | // When the page is ready, call the init function.
123 | window.addEventListener("load", init_);
124 | })();
125 |
--------------------------------------------------------------------------------
/samples/web/Continote/public/scripts/sample-config.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2017 Google Inc. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a
6 | * copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations
14 | * under the License.
15 | */
16 |
17 | /**
18 | * This script sets up Firebase.
19 | *
20 | * Remember to include this script in the of a page if you plan on using
21 | * Firebase within that page.
22 | */
23 | (function() {
24 | 'use strict';
25 |
26 | /**
27 | * Firebase will be initialized with this config object.
28 | *
29 | * @type {!Object}
30 | * @const
31 | */
32 | var config_ = {
33 | apiKey: "[TODO: YOUR-API-KEY-HERE]",
34 | authDomain: "[TODO: YOUR-AUTH-DOMAIN-HERE]",
35 | databaseURL: "[TODO: YOUR-DATABASE-URL-HERE]",
36 | projectId: "[TODO: YOUR-PROJECT-ID-HERE]"
37 | };
38 | firebase.initializeApp(config_);
39 | })();
40 |
--------------------------------------------------------------------------------
/samples/web/Continote/public/scripts/utils.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2017 Google Inc. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a
6 | * copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations
14 | * under the License.
15 | */
16 |
17 | /**
18 | * This object provides some simple utility functions.
19 | *
20 | * Remember to include this script in the of a page if you plan on
21 | * using any of these utilities within that page.
22 | *
23 | * @type {!Object}
24 | * @const
25 | */
26 | var Utils = (function() {
27 | 'use strict';
28 |
29 | /**
30 | * This is the class which, if applied to an element, hides that element.
31 | *
32 | * @type {!string}
33 | * @const
34 | */
35 | var hiddenClass_ = "hidden";
36 |
37 | /**
38 | * This is the class which, if applied to an element, means
39 | * the text within the element should be considered a placeholder.
40 | *
41 | * @type {!string}
42 | * @const
43 | */
44 | var placeholderClass_ = "placeholder";
45 |
46 | /**
47 | * This is the name of the click event type.
48 | *
49 | * @type {!string}
50 | * @const
51 | */
52 | var clickEventType_ = "click";
53 |
54 | /**
55 | * Shows the provided DOM element if it is currently hidden.
56 | *
57 | * @function
58 | * @param {!Element} element
59 | * @const
60 | */
61 | var showElement_ = function(element) {
62 | element.classList.remove(hiddenClass_);
63 | };
64 |
65 | /**
66 | * Hides the provided DOM element if it is currently shown.
67 | *
68 | * @function
69 | * @param {!Element} element
70 | * @const
71 | */
72 | var hideElement_ = function(element) {
73 | element.classList.add(hiddenClass_);
74 | };
75 |
76 | return {
77 |
78 | /**
79 | * Shows all DOM elements with the provided className.
80 | *
81 | * @function
82 | * @param {!string} className
83 | * @const
84 | */
85 | showAllElementsWithClassName: function(className) {
86 | var elements = document.getElementsByClassName(className);
87 | for (var i = 0; i < elements.length; i++) {
88 | showElement_(elements[i]);
89 | }
90 | },
91 |
92 | /**
93 | * Hides all DOM elements with the provided className.
94 | *
95 | * @function
96 | * @param {!string} className
97 | * @const
98 | */
99 | hideAllElementsWithClassName: function(className) {
100 | var elements = document.getElementsByClassName(className);
101 | for (var i = 0; i < elements.length; i++) {
102 | hideElement_(elements[i]);
103 | }
104 | },
105 |
106 | /**
107 | * Enables the provided button element if it is currently disabled,
108 | * and adds the provided click event listener to the button
109 | * if the event listener is not already attached to it.
110 | *
111 | * @function
112 | * @param {!Element} button
113 | * @param {?ClickEventListener} clickEventListener
114 | * @const
115 | */
116 | enableButtonAndAddClickListener: function(button, clickEventListener) {
117 | button.disabled = false;
118 | if (clickEventListener) {
119 | button.addEventListener(clickEventType_, clickEventListener);
120 | }
121 | },
122 |
123 | /**
124 | * Disables the provided button element if it is currently enabled,
125 | * and removes the provided click event listener from the button
126 | * if the event listener is currently attached to it.
127 | *
128 | * @function
129 | * @param {!Element} button
130 | * @param {?ClickEventListener} clickEventListener
131 | * @const
132 | */
133 | disableButtonAndRemoveClickListener: function(button, clickEventListener) {
134 | button.disabled = true;
135 | if (clickEventListener) {
136 | button.removeEventListener(clickEventType_, clickEventListener);
137 | }
138 | },
139 |
140 | /**
141 | * Puts the given text, or the given placeholder if the text
142 | * is null or empty, within the element.
143 | *
144 | * @function
145 | * @param {?string} text
146 | * @param {!string} placeholder
147 | * @param {!Element} element
148 | * @const
149 | */
150 | putTextOrPlaceholderInElement: function(text, placeholder, element) {
151 | if (text && text.length > 0) {
152 | element.textContent = text;
153 | element.classList.remove(placeholderClass_);
154 | } else {
155 | element.textContent = placeholder;
156 | element.classList.add(placeholderClass_);
157 | }
158 | },
159 |
160 | /**
161 | * Appends an element based on the provided template to the provided
162 | * container.
163 | *
164 | * @function
165 | * @param {!string} template - The template to create the new element
166 | * based upon.
167 | * @param {!Element} container - The container to append the new element
168 | * (created from the template) to.
169 | * @returns {?Element} - The new element that is now in the container (or
170 | * null if no element could be appended).
171 | * @const
172 | */
173 | appendElementBasedOnTemplateToContainer: function(template, container) {
174 | if (!template || !container) {
175 | // This should never happen, but just in case.
176 | return null;
177 | }
178 |
179 | // The template will be added to this container
180 | // (which will not be anywhere in the actual page DOM) temporarily,
181 | // and then moved to the final container.
182 | // This is needed so there is an actual element created from the
183 | // template.
184 | var temporaryContainer = document.createElement("div");
185 | temporaryContainer.innerHTML = template;
186 |
187 | // Get the element to put in the actual container from the temporary
188 | // container, then append that element to said actual container.
189 | var element = temporaryContainer.firstElementChild;
190 | container.appendChild(element);
191 |
192 | return element;
193 | }
194 | }
195 | }());
196 |
197 | // Below are extra JSDoc definitions to describe the callback functions
198 | // this utility object expects.
199 |
200 | /**
201 | * The standard click event callback.
202 | *
203 | * @callback ClickEventListener
204 | * @param {!Object} event
205 | */
206 |
--------------------------------------------------------------------------------
/samples/web/Continote/public/styles/all-pages.css:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2017 Google Inc. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the
10 | * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
11 | * express or implied. See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 |
15 | /**
16 | * These styles apply to all popup pages.
17 | * Thy are based on the Material Design Lite samples provided here:
18 | * https://getmdl.io/templates/index.html
19 | */
20 |
21 | html,
22 | body {
23 | margin: 0;
24 | padding: 0;
25 | font-family: 'Roboto', 'Helvetica', sans-serif;
26 | }
27 |
28 | .app-title {
29 | font-weight: bold;
30 | }
31 |
32 | .mdl-navigation {
33 | text-transform: uppercase;
34 | }
35 |
36 | .mdl-layout__content {
37 | padding: 32px;
38 | }
39 |
40 | .mdl-layout__content section {
41 | max-width: 960px;
42 | }
43 |
44 | .mdl-layout__content section:not(:last-child) {
45 | margin-bottom: 32px !important;
46 | }
47 |
48 | .mdl-card {
49 | height: auto;
50 | min-height: 0;
51 | display: -webkit-flex;
52 | display: -ms-flexbox;
53 | display: flex;
54 | -webkit-flex-direction: column;
55 | -ms-flex-direction: column;
56 | flex-direction: column;
57 | }
58 |
59 | .mdl-card > * {
60 | height: auto;
61 | }
62 |
63 | .mdl-card .mdl-card__title {
64 | padding: 20px 20px 0;
65 | }
66 |
67 | .mdl-card .mdl-card__supporting-text {
68 | margin: 20px;
69 | -webkit-flex-grow: 1;
70 | flex-grow: 1;
71 | padding: 0;
72 | }
73 |
74 | .mdl-card__actions {
75 | margin: 0;
76 | padding: 12px 20px;
77 | }
78 |
79 | a.current,
80 | a:hover {
81 | font-weight: bold;
82 | }
83 |
84 | #firebaseui-container .firebaseui-idp-google {
85 | background-color: #FFFFFF !important;
86 | }
87 |
88 | #firebaseui-container .firebaseui-idp-facebook {
89 | background-color: #3b5998 !important;
90 | }
91 |
92 | #note-list {
93 | margin: 0;
94 | padding: 0;
95 | }
96 |
97 | #note-list .note-list-item .mdl-list__item-primary-content {
98 | width: 50%;
99 | }
100 |
101 | #note-list .note-list-item {
102 | height: auto;
103 | }
104 |
105 | #note-list .note-list-item .note-title {
106 | font-weight: bold;
107 | }
108 |
109 | #note-list .note-list-item .note-actions {
110 | width: 50%;
111 | text-align: right;
112 | }
113 |
114 | #note-list .note-list-item .note-actions button {
115 | margin-left: 10px;
116 | margin-bottom: 10px;
117 | }
118 |
119 | #note-editor .mdl-textfield {
120 | width: 100%;
121 | }
122 |
123 | #note-editor #note-title-input {
124 | font-weight: bold;
125 | }
126 |
127 | #save-note-button {
128 | margin-left: 10px;
129 | }
130 |
131 | .truncate-to-single-line {
132 | white-space: nowrap !important;
133 | overflow: hidden !important;
134 | text-overflow: ellipsis !important;
135 | }
136 |
137 | .hidden {
138 | display: none !important;
139 | }
140 |
141 | .placeholder {
142 | font-style: italic;
143 | }
144 |
--------------------------------------------------------------------------------
/samples/web/Continote/sample-database.rules.json:
--------------------------------------------------------------------------------
1 | // The contents of this file are to be included in another, more complete database
2 | // rules file during the Setup process. See this sample's README.
3 |
4 | // This node stores all notes created by users in Continote.
5 | "notes": {
6 |
7 | // Notes are user specific, so here we store a list of user-private nodes.
8 | "$uid": {
9 | ".read": "$uid === auth.uid",
10 | ".write": "$uid === auth.uid",
11 |
12 | // A user can have many notes, so here we store a list of note nodes.
13 | "$noteid": {
14 | ".validate": "newData.hasChildren(['title', 'content'])",
15 |
16 | // The title of this note.
17 | "title": {
18 | ".validate": "newData.isString()"
19 | },
20 |
21 | // The main content of this note.
22 | "content": {
23 | ".validate": "newData.isString()"
24 | },
25 |
26 | // Prevent extraneous data from being added to this note.
27 | "$other": {
28 | ".validate": false
29 | }
30 | }
31 | }
32 | },
33 |
--------------------------------------------------------------------------------