Skip to content

Commit a568640

Browse files
author
paperbits
committed
initial commit
0 parents  commit a568640

15 files changed

+1182
-0
lines changed

.gitattributes

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
*.pfx binary
2+
*.ico binary
3+
*.svg binary
4+
*.jpg binary
5+
*.png binary
6+
*.exe binary
7+
*.eot binary
8+
*.woff binary
9+
*.woff2 binary
10+
*.ttf binary
11+
*.otf binary
12+
*.cdr binary

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
node_modules/
2+
bower_components/
3+
public/
4+
typings/globals/
5+
.idea/
6+
.vscode/

LICENSE

Lines changed: 674 additions & 0 deletions
Large diffs are not rendered by default.

bower.json

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
"name": "paperbits-firebase",
3+
"homepage": "https://github.com/paperbits/paperbits-firebase",
4+
"authors": [
5+
"paperbits <[email protected]>"
6+
],
7+
"description": "Firebase client library for PaperBits components.",
8+
"main": [
9+
"src/scripts/firebaseService.ts",
10+
"src/scripts/firebaseFileStorage.ts",
11+
"src/scripts/firebaseObjectStorage.ts",
12+
"src/scripts/registrations.firebase.ts"
13+
],
14+
"keywords": [
15+
"paperbits",
16+
"firebase"
17+
],
18+
"license": "GPLv3",
19+
"ignore": [
20+
"**/.*",
21+
"node_modules",
22+
"bower_components"
23+
]
24+
}

gulpfile.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
var gulp = require("gulp");
2+
var bower = require("main-bower-files");
3+
var concat = require("gulp-concat");
4+
var uglify = require("gulp-uglify");
5+
var filter = require("gulp-filter");
6+
var typescript = require("typescript");
7+
var typescriptCompiler = require("gulp-typescript");
8+
9+
function handleErrors(error) {
10+
console.log("ERROR:");
11+
console.log(error.toString());
12+
this.emit("end");
13+
}
14+
15+
gulp.task("default", function () {
16+
var tsProject = typescriptCompiler.createProject("tsconfig.json", {
17+
sortOutput: true,
18+
typescript: typescript
19+
});
20+
21+
var tsResult = tsProject
22+
.src()
23+
.pipe(typescriptCompiler(tsProject));
24+
25+
return tsResult.js
26+
.pipe(concat("paperbits-firebase.min.js"))
27+
.pipe(uglify({ mangle: false }))
28+
.pipe(gulp.dest("public"));
29+
});

package.json

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"name": "vienna",
3+
"private": true,
4+
"version": "0.1.0",
5+
"description": "Vienna",
6+
"license": "GPL2",
7+
"devDependencies": {
8+
"bower": "^1.3.1",
9+
"firebase": "^3.2.0",
10+
"firebase-tools": "^3.0.4",
11+
"gulp": "^3.9.0",
12+
"gulp-concat": "^2.6.0",
13+
"gulp-filter": "^4.0.0",
14+
"gulp-less": "^3.0.3",
15+
"gulp-typescript": "^2.13.6",
16+
"gulp-uglify": "^1.5.4",
17+
"main-bower-files": "^2.8.0",
18+
"typescript": "^2.0.0",
19+
"typings": "^1.3.1",
20+
"yargs": "^4.8.0"
21+
}
22+
}

src/firebaseFileStorage.ts

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
module Paperbits.Firebase {
2+
export class FirebaseFileStorage implements Paperbits.Persistence.IFileStorage {
3+
private firebaseService: FirebaseService;
4+
5+
constructor(firebaseService: FirebaseService) {
6+
this.firebaseService = firebaseService;
7+
}
8+
9+
public uploadFile(name: string, file: Blob): ProgressPromise<void> {
10+
return new ProgressPromise<void>((resolve, reject, progress) => {
11+
this.firebaseService.getStorageRef().then((storageRef) => {
12+
var uploadTask = storageRef
13+
.child(name)
14+
.put(file);
15+
16+
uploadTask.on("state_changed",
17+
(snapshot: FirebaseUploadSnapshot) => {
18+
progress((snapshot.bytesTransferred / snapshot.totalBytes) * 100);
19+
},
20+
(error: FirebaseUploadError) => {
21+
console.error(error);
22+
reject()
23+
},
24+
resolve);
25+
});
26+
});
27+
}
28+
29+
public getDownloadUrl(filename: string): Promise<string> {
30+
return this.firebaseService.getStorageRef().then((storageRef) => {
31+
return storageRef.child(filename).getDownloadURL();
32+
});
33+
}
34+
35+
public deleteFile(filename: string): Promise<void> {
36+
return new Promise<void>((resolve, reject) => {
37+
this.firebaseService.getStorageRef().then((storageRef) => {
38+
storageRef
39+
.child(filename)
40+
.delete().then(() => {
41+
resolve();
42+
});
43+
});
44+
});
45+
}
46+
}
47+
}

src/firebaseObjectStorage.ts

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
module Paperbits.Firebase {
2+
import IObjectStorage = Paperbits.Persistence.IObjectStorage;
3+
import FirebaseService = Paperbits.Firebase.FirebaseService;
4+
5+
export class FirebaseObjectStorage implements IObjectStorage {
6+
private firebaseService: FirebaseService;
7+
8+
constructor(firebaseService: FirebaseService) {
9+
this.firebaseService = firebaseService;
10+
}
11+
12+
public addObject<T>(path: string, dataObject: T): Promise<void> {
13+
return new Promise<void>((resolve, reject) => {
14+
this.firebaseService.getDatabaseRef().then((databaseRef) => {
15+
if (path) {
16+
databaseRef.child(path).set(dataObject, (error) => {
17+
if (error) {
18+
reject([`Could not add object '${path}'. Error: ${error}.`]);
19+
} else {
20+
resolve();
21+
}
22+
});
23+
}
24+
else {
25+
databaseRef.update(dataObject, (error) => {
26+
if (error) {
27+
reject([`Could not add object '${path}'. Error: ${error}.`]);
28+
} else {
29+
resolve();
30+
}
31+
});
32+
}
33+
});
34+
});
35+
}
36+
37+
public getObject<T>(path: string): Promise<T> {
38+
return new Promise<T>((resolve, reject) => {
39+
this.firebaseService.getDatabaseRef().then((databaseRef) => {
40+
databaseRef.child(path).once("value",
41+
(snapshot) => {
42+
resolve(snapshot.val());
43+
}, (error) => {
44+
reject([`Could not retrieve object '${path}'. Error: ${error}.`]);
45+
});
46+
});
47+
});
48+
}
49+
50+
public deleteObject(path: string): Promise<void> {
51+
return new Promise<void>((resolve, reject) => {
52+
this.firebaseService.getDatabaseRef().then((databaseRef) => {
53+
databaseRef.child(path).remove((error: string) => {
54+
if (error) {
55+
reject([`Could not delete object '${path}'. Error: ${error}.`]);
56+
} else {
57+
resolve();
58+
}
59+
});
60+
});
61+
});
62+
}
63+
64+
public updateObject<T>(path: string, dataObject: T): Promise<T> {
65+
return new Promise<T>((resolve, reject) => {
66+
this.firebaseService.getDatabaseRef().then((databaseRef) => {
67+
databaseRef.child(path).update(dataObject,
68+
error => {
69+
if (error) {
70+
reject([`Could not update object '${path}'. Error: ${error}`]);
71+
} else {
72+
resolve(dataObject);
73+
}
74+
});
75+
});
76+
});
77+
}
78+
79+
public searchObjects<T>(path: string, propertyNames?: Array<string>, searchValue?: string, startAtSearch?: boolean, skipLoadObject?: boolean): Promise<Array<T>> {
80+
return new Promise<Array<T>>((resolve, reject) => {
81+
this.firebaseService.getDatabaseRef().then((databaseRef) => {
82+
if (propertyNames && propertyNames.length && searchValue) {
83+
var searchTasks = propertyNames.map((propertyName) => {
84+
let query: FirebaseQuery = startAtSearch
85+
? databaseRef.child(path).orderByChild(propertyName).startAt(searchValue)
86+
: databaseRef.child(path).orderByChild(propertyName).equalTo(searchValue);
87+
88+
return query.once("value").then((result) => this.collectResult(result));
89+
});
90+
91+
Promise.all(searchTasks).then(
92+
(searchTaskResults) => {
93+
resolve(_.flatten(searchTaskResults));
94+
},
95+
(error) => {
96+
return [`Could not search object '${path}'. Error: ${error}.`];
97+
});
98+
}
99+
else {
100+
//return all objects
101+
102+
databaseRef.child(path).once("value",
103+
(objectData) => {
104+
let result = this.collectResult(objectData);
105+
resolve(result);
106+
},
107+
(error) => {
108+
reject([`Could not search object '${path}'. Error: ${error}.`]);
109+
}
110+
);
111+
}
112+
});
113+
});
114+
}
115+
116+
private collectResult(objectData) {
117+
let result = [];
118+
119+
if (objectData.hasChildren()) {
120+
let items = objectData.val();
121+
122+
if (items) {
123+
if (_.isArray(items)) {
124+
items.map((item) => result.push(item));
125+
} else {
126+
_.mapObject(items, (item) => {
127+
result.push(item)
128+
});
129+
}
130+
}
131+
}
132+
return result;
133+
};
134+
}
135+
}

src/firebaseService.ts

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
module Paperbits.Firebase {
2+
import ISettingsProvider = Paperbits.Configuration.ISettingsProvider;
3+
import IEventManager = Paperbits.IEventManager;
4+
5+
export class FirebaseService {
6+
private settingsProvider: ISettingsProvider;
7+
private eventManager: IEventManager;
8+
private tenantRootKey: string;
9+
private preparingPromise: Promise<any>;
10+
11+
constructor(settingsProvider: ISettingsProvider, eventManager: IEventManager) {
12+
this.settingsProvider = settingsProvider;
13+
this.eventManager = eventManager;
14+
15+
// rebinding...
16+
this.onConfiurationLoaded = this.onConfiurationLoaded.bind(this);
17+
}
18+
19+
private onConfiurationLoaded(firebaseSettings: FirebaseConfig): Promise<any> {
20+
//this.tenantRootKey = `tenants/${config.tenantId}`;
21+
this.tenantRootKey = "tenants/default";
22+
23+
firebase.initializeApp(firebaseSettings); // This can be called only once
24+
25+
var connectedRef = firebase.database().ref(".info/connected");
26+
27+
connectedRef.on("value", (snapshot) => {
28+
if (snapshot.val() === true) {
29+
this.eventManager.dispatchEvent("onOnlineStatusChanged", "online");
30+
}
31+
else {
32+
this.eventManager.dispatchEvent("onOnlineStatusChanged", "offline");
33+
}
34+
});
35+
36+
return Promise.resolve();
37+
}
38+
39+
public authenticate(): Promise<any> {
40+
return firebase.auth().signInAnonymously().then((result) => {
41+
console.info("Firebase: Authenticated anonymously.");
42+
});
43+
44+
// TODO: Uncomment for Google Auth
45+
46+
// firebase.auth().getRedirectResult().then((result) => {
47+
// if (!result.credential) {
48+
// console.log(result);
49+
// var provider = new firebase.auth.GoogleAuthProvider();
50+
// firebase.auth().signInWithRedirect(provider);
51+
// }
52+
// console.info("Firebase: Authenticated with Google.");
53+
// });
54+
}
55+
56+
public getFirebaseRef(): Promise<any> {
57+
if (this.preparingPromise) {
58+
return this.preparingPromise
59+
}
60+
61+
this.preparingPromise = new Promise((resolve, reject) => {
62+
this.settingsProvider.getSetting("firebase")
63+
.then(this.onConfiurationLoaded)
64+
.then(this.authenticate)
65+
.then(() => {
66+
resolve(firebase);
67+
});
68+
});
69+
70+
return this.preparingPromise;
71+
}
72+
73+
public getDatabaseRef(): Promise<FirebaseDatabaseRef> {
74+
return new Promise<FirebaseDatabaseRef>((resolve, reject) => {
75+
this.getFirebaseRef().then((firebaseRef) => {
76+
let databaseRef = firebaseRef.database().ref(this.tenantRootKey);
77+
resolve(databaseRef);
78+
});
79+
});
80+
}
81+
82+
public getStorageRef(): Promise<FirebaseStorageRef> {
83+
return new Promise<FirebaseStorageRef>((resolve, reject) => {
84+
this.getFirebaseRef().then((firebaseRef) => {
85+
let storageRef = firebaseRef.storage().ref(this.tenantRootKey);
86+
resolve(storageRef);
87+
});
88+
});
89+
}
90+
}
91+
}

src/registrations.firebase.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
module Paperbits.Registrations {
2+
export class FirebaseRegistration implements IRegistration {
3+
public register(injector: IInjector): void {
4+
injector.bindSingleton("firebaseService", Paperbits.Firebase.FirebaseService);
5+
injector.bindSingleton("fileStorage", Paperbits.Firebase.FirebaseFileStorage);
6+
7+
injector.bindFactory<Paperbits.Persistence.IObjectStorage>("objectStorage", (ctx: Paperbits.IInjector) => {
8+
var firebaseService = ctx.resolve<Paperbits.Firebase.FirebaseService>("firebaseService");
9+
var objectStorage = new Paperbits.Firebase.FirebaseObjectStorage(firebaseService);
10+
var eventManager = ctx.resolve<Paperbits.IEventManager>("eventManager");
11+
12+
return new Paperbits.Persistence.CachedObjectStorage(objectStorage, eventManager);
13+
});
14+
}
15+
}
16+
}

0 commit comments

Comments
 (0)