$firebaseSimpleLoginProvider not found - firebase

I'm having trouble getting the facebookSimpleLogin angularfire service to be dependency injected into one of my angular js services.
angular.module('cakethursdayApp')
.service('FacebookAuthService', function FacebookAuthService($firebaseSimpleLogin) {
......
});
I am getting the error "Error: [$injector:unpr] Unknown provider: $firebaseSimpleLoginProvider <- $firebaseSimpleLogin <- FacebookAuthService"
I have my scripts loaded in the following order
<script src="bower_components/firebase/firebase.js"></script>
<script src="bower_components/firebase-simple-login/firebase-simple-login.js"></script>
<script src="bower_components/angularfire/angularfire.js"></script>

Generally speaking when you have a "missing dependency" always take a look at your module declaration's dependency injection.
angular.module(modulename, [list of dependencies to inject]).
Anytime you're using firebase (with angularfire I know specifically) you'll want something like this
angular.module(modulename, ['firebase'])
Additionally (often times you'll need it) in your controller definition as well.
function myCtrl($scope, $firebase)
This way when you want to setup a reference to your firebase URL it'll look like this:
var FB = "https://##instance##.firebaseio.com/"; //your Firebase address
var ref = new Firebase(FB); // Creates a new instance of AngularFire
$scope.variableNames= $firebase(ref); // the angularfire "firebase" service reference.
(please correct me if my comments are wrong up there, this is my understanding of the code)
for use in ng-repeat or other operations
(For Example)
<div ng-repeat="variable in variableNames">
{{variable}}
</div>

You need to make two changes in current code to make it working:
angular.module('cakethursdayApp', ['firebase'])
.service('FacebookAuthService', function FacebookAuthService($firebaseAuth) {
......
});
Inject AngularFire module as dependency
Replace $firebaseSimpleLogin with $firebaseAuth because
$firebaseSimpleLogin was dropped/removed in of 0.9.0.

Related

How to release or distribute an application that uses mikro-orm?

In the configuration I have to specify the paths to .js and .ts files defining entities:
MikroORM.init({
...
entitiesDirs: ["build/entities"],
entitiesDirsTs: ["src/entities"],
});
So, when I will go to release or distribute the application. Will I need distribute the typescript code too? or will I need distribute only the cache generated? or will I need distribute both? or... none?
As of MikroORM v2.2
Now you can work with default metadata provider, it will require entity source files only if you do not provide entity or type options in your decorators (you can use entity callback to use reference to entity class instead of using string name in type, handle for refactoring via IDE like webstorm).
Original answer:
You should ship the typescript code too, and let the cache regenerate on the server - cache would be rebuilt anyway as it checks absolute path to cached entity for invalidation.
You could implement your own cache adapter or metadata provider to get around this, if you don't want to ship the typescript code.
This is how you could implement custom metadata provider that simply throws error when the type option is missing:
import { MetadataProvider, Utils } from 'mikro-orm';
import { EntityMetadata } from 'mikro-orm/dist/decorators';
export class SimpleMetadataProvider extends MetadataProvider {
async loadEntityMetadata(meta: EntityMetadata, name: string): Promise<void> {
// init types and column names
Object.values(meta.properties).forEach(prop => {
if (prop.entity) {
prop.type = Utils.className(prop.entity());
} else if (!prop.type) {
throw new Error(`type is missing for ${meta.name}.${prop.name}`)
}
});
}
}
Then provide this class when initializing:
const orm = await MikroORM.init({
// ...
metadataProvider: SimpleMetadataProvider,
});
The value of type should be JS types, like string/number/Date... You can observe your cached metadata to be sure what values should be there.
Also keep in mind that without TS metadata provider, you will need to specify entity type in #ManyToOne decorator too (either via entity callback, or as a string via type).

Firebase - Cloud Function - "Error: Cloud function needs to be called with an event parameter."

I am trying to create a cloud function for creating an user profile when a new user user is created(gosh a lot of "create).
I implemented this function:
exports.createProfile = functions.auth.user()
.onCreate( (userRecord, context) => {
return admin.database().ref(`/userProfile/${userRecord.data.uid}`).set({
email: userRecord.data.email
});
});
but when I create a new user, I got this error:
Error: Cloud function needs to be called with an event parameter.If you are writing unit tests, please use the Node module firebase-functions-fake.
at Object.<anonymous> (/srv/node_modules/firebase-functions/lib/cloud-functions.js:84:19)
at Generator.next (<anonymous>)
at /srv/node_modules/firebase-functions/lib/cloud-functions.js:28:71
at new Promise (<anonymous>)
at __awaiter (/srv/node_modules/firebase-functions/lib/cloud-functions.js:24:12)
at cloudFunction (/srv/node_modules/firebase-functions/lib/cloud-functions.js:82:36)
at /worker/worker.js:731:24
at <anonymous>
at process._tickDomainCallback (internal/process/next_tick.js:228:7)
is anyone facing something like that?
any solution so far?
Kind Regards
According to the docs the onCreate takes only an event as the parameter and there's no need for context (in this case userRecord): https://firebase.google.com/docs/functions/auth-events
You should then be able to simply access the uid via userRecord.uid :)
I upgraded to the latest firebase-functions, which solved the problem on my system. Run
npm outdated
to see if your firebase-functions is really up to date. NPM by itself won't update past semvers.
My guess is that firebase-functions defines an event class, and it is their internals which pass this event object to the user-defined callback. So if you are using an older version of firebase-functions, the callback is not receiving an "event parameter"
Don't have enough points to comment on Alchemist Shahed's answer, but the docs actually seem to be a bit conflicting on how to call onCreate().
https://firebase.google.com/docs/functions/auth-events#trigger_a_function_on_user_creation
says:
exports.sendWelcomeEmail =
functions.auth.user().onCreate((user) => {
// ...
});
But the upgrade guide
https://firebase.google.com/docs/functions/beta-v1-diff#authentication
shows
exports.authAction =
functions.auth.user().onCreate((userRecord, context) => {
const creationTime = userRecord.metadata.creationTime; //
// 2016-12-15T19:37:37.059Z
const lastSignInTime = userRecord.metadata.lastSignInTime;
// 2018-01-03T16:23:12.051Z
}
and https://firebase.google.com/docs/reference/functions/providers_auth_.userbuilder#on-create
also shows the (user: UserRecord, context: EventContext): PromiseLike<any> | any handler
So it is not clear if the context argument is needed or not.

Meteor Package: Add Custom Options

I've created a Meteor smart package, and would like to add user generated custom options to the API.
However, I'm having issues due to Meteor's automatic load ordering.
SocialButtons.config({
facebook: false
});
This runs a config block that adds defaults.
SocialButtons.config = function (options) {
... add to options if valid ...
};
Which in turn grabs a set of defaults:
var defaults = {
facebook: true,
twitter: true
}
Which are mixed into the settings.
var settings = _.extend(defaults, options);
...(program starts, uses settings)...
The problem is that everything must run in the proper order.
Create SocialButtons object
Run the optional SocialButtons.config()
Create settings & run the program
How can I control the load order in Meteor without knowing where a user might place the optional configuration?
Step 2 will be in a different folder/file, but must run sandwiched between steps 1 & 3.
You can't really control load order right now so it's not guaranteed but placing files at /libs are loaded first but in your case it's doesn't really matter it might be something else here is a very simple package you can view the source on how I setup default options and allow to replace those easily https://github.com/voidale/meteor-bootstrap-alerts
Figured this out.
Put your package into a /lib directory.
Include a setup function that sets the settings when called, and loads the data
Return the data from the startup function
In this case:
SocialButtons.get = function () {
return initButtons();
}
function initButtons() { ... settings, startup, return final value ... }

Is there a way to integrate handlebars-helpers with hapi?

I would like to use the handlebars-helpers node module with my handlebars templates. I'm using hapi as my framework which supports handlebars. I haven't found any documentation or examples that shows how to use handlebars-helpers with hapi using handlebars as the view engine.
Is it possible and if so, what is the solution?
after start hapi server
// hapi v17
try {
await server.start();
} catch (err) {
throw err;
}
//......
// add some handlebars helpers
let hbs = server.realm.plugins.vision.manager._engines.hbs;
// console.log('handlebars_helpers', handlebars_helpers);
if (handlebars_helpers) {
for (let key in handlebars_helpers) {
if (key) {
// console.log('key', key, helpers[key]);
hbs.module.helpers[key] = handlebars_helpers[key];
}
}
}
//check your helper is registered
// console.log('hbs.module.helpers', hbs.module.helpers);
// add some handlebars helpers
I don't think it's currently possible according to hapijs api docs for views:
http://hapijs.com/api#serverviewsoptions
helpersPath - the directory path where helpers are located. Helpers are functions used within templates to perform transformations and other data manipulations using the template context or other inputs. Each '.js' file in the helpers directory is loaded and the file name is used as the helper name. The files must export a single method with the signature function(context) and return a string. Sub-folders are not supported and are ignored. Defaults to no helpers support (empty path). Note that jade does not support loading helpers this way.
Looks as though handlebars-helpers has a different signature than what is required by hapi

Where to put native code for push notifications with new Meteor Mobile platform

After reviewing the new Mobile features with latest 1.0 version of Meteor, I'm not seeing where I would modify the Cordova code to add custom capabilities. For instance, I want to implement push notifications for my application on both iOS and Android. In both cases I would need to write some native code so that I could get devices registered and accept push notification messages.
Currently, I'm using MeteorRider to accomplish this and it works great. I have 3 separate projects for Meteor, Android and iOS. In the latter 2, I put the native code there necessary to accomplish this. One thing is for certain, you have to update the bootstrap classes in Cordova to allow registrations to work.
In Meteor 1.0, how would I go about accomplishing this with the out-of-the-box mobile feature?
Here's the objective-C code for accepting push notification registration responses that is required in Cordova's AppDelegate:
- (void) application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
NSLog( #"Device token is: %#", deviceToken);
// Convert to string that can be stored in DB
NSString *regId = [[deviceToken description] stringByReplacingOccurrencesOfString:#"<" withString:#""];
regId = [regId stringByReplacingOccurrencesOfString:#">" withString:#""];
regId = [regId stringByReplacingOccurrencesOfString: #" " withString: #""];
[[ApplePushNotificationService sharedInstance] application:application uploadDeviceToken:regId];
}
- (void)application:(UIApplication*)application didFailToRegisterForRemoteNotificationsWithError:(NSError*)error
{
NSLog(#"Failed to get token, error: %#", error);
}
TL;DR : The cordova project is in the .meteor/local/cordova-build subfolder.
The default AppDelegate.m gets created in the .meteor/local/cordova-build/platforms/ios/***YOUR_APP_NAME***/Classes subfolder.
If you add a top-level folder called cordova-build-override to your meteor project, the directory tree that it contains will be added to the .meteor/local/cordova-build folder just before the build and compilation step.
So, put your custom AppDelegate.m in a new folder called cordova-build-override/platforms/ios/***YOUR_APP_NAME***/Classes .
mkdir -p cordova-build-override/platforms/ios/foo/Classes
cp .meteor/local/cordova-build/platforms/ios/foo/Classes/AppDelegate.m cordova-build-override/platforms/ios/foo/Classes
The Meteor-Cordova integration page on the GitHub Meteor wiki is the best place (so far) to find the details of cordova development with meteor.
You put your cordova-specific code in plain javascript. It's best not to modify the native code if at all possible; instead, see if you can write your own cordova plugin and use it from your meteor app. The cordova PushPlugin plugin might do what you're looking for, but if not, you can use it as a reference.
This example below will create a new iOS app that uses a non-meteor cordova plugin, from scratch.
NOTE: This is a bare minimum example. Look at the meteor cordova camera plugin for a full example. The code below is based on that plugin.
# create a meteor app foo
meteor create foo
cd foo
# add the iOS cordova platform
meteor add-platform ios
# create a new meteor package, foo-camera.
# NOTE: You need to substitute your own meteor.com developer ID here
meteor create --package your_meteor_developer_id:foo-camera
Now, edit the packages/your_meteor_developer_id:foo-camera/package.js file to add the following:
// Add the camera cordova plugin at version 0.3.3
Cordova.depends({
'org.apache.cordova.camera': '0.3.3'
});
EDIT 1: This causes the plugin to be downloaded to your cordova plugins folder.
You can refer to a git tarball instead of a version number e.g. :
Cordova.depends({
'com.phonegap.plugins.facebookconnect': 'https://github.com/Wizcorp/phonegap-facebook-plugin/tarball/0e61babb65bc1716b957b6294c7fdef3ce6ace79'
});
source: meteor cordova wiki
While we're at it, limit our code to run only on the client, and export our FooCamera object so it can be used in the rest of our meteor javascript:
Package.onUse(function(api) {
api.versionsFrom('1.0');
api.export('FooCamera');
api.addFiles('your_meteor_developer_id:foo-camera.js','client');
});
Edit 2:
If your cordova plugin needs special configuration, you can define this in your meteor app's
mobile configuration file. It will get copied into
your app's config.xml .
E.g.
// ===== mobile-config.js ======
// Set PhoneGap/Cordova preferences
App.setPreference('SOME_SPECIFIC_PLUGIN_KEY','SOME_SPECIFIC_PLUGIN_VAL');
Your app's config.xml will then eventually result in the following:
<preference name="SOME_SPECIFIC_PLUGIN_KEY" value="SOME_SPECIFIC_PLUGIN_VAL"/>
Next, edit the JavaScript file in your package ( packages/your_meteor_developer_id:foo-camera/your_meteor_developer_id:foo-camera.js ) to expose the cordova functionality in a meteor-like manner. Use the official meteor mobile package examples as a reference.
(the code below is stolen shamelessly from the meteor github repo ) :
FooCamera = {};
FooCamera.getPicture = function (options, callback) {
// if options are not passed
if (! callback) {
callback = options;
options = {};
}
var success = function (data) {
callback(null, "data:image/jpeg;base64," + data);
};
var failure = function (error) {
callback(new Meteor.Error("cordovaError", error));
};
// call the cordova plugin here, and pass the result to our callback.
navigator.camera.getPicture(success, failure,
_.extend(options, {
quality: options.quality || 49,
targetWidth: options.width || 640,
targetHeight: options.height || 480,
destinationType: Camera.DestinationType.DATA_URL
})
);
};
Now, add your new (local) package to your meteor app.
meteor add your_meteor_developer_id:foo-camera
Edit your application's main HTML and JS to use your new meteor package.
In your foo.html , replace the hello template with this:
<template name="hello">
<button>Take a Photo</button>
{{#if photo}}
<div>
<img src={{photo}} />
</div>
{{/if}}
</template>
In your foo.js , replace the button click event handler with this:
Template.hello.helpers({
photo: function () {
return Session.get("photo");
}
});
Template.hello.events({
'click button': function () {
var cameraOptions = {
width: 800,
height: 600
};
FooCamera.getPicture(cameraOptions, function (error, data) {
Session.set("photo", data);
});
}
});
Now, plug your device in, make sure it's on the same network as your computer, and start both the meteor server and the ios app.
meteor run ios-device
# If you want to just use the emulator, use the following instead.
# but of course the camera won't work on the emulator.
#meteor run ios
XCode will open. You may need to set up your certificates and provisioning profiles before running your app (from XCode).
In another terminal, tail the logs:
tail -f .meteor/local/cordova-build/platforms/ios/cordova/console.log
Finally, publish your excellent meteor cordova plugin so that everyone else can use it. Edit package.js as per the meteor docs. Then:
cd packages/your_meteor_developer_id\:foo-camera
meteor publish

Resources