We have an existing mongodb which I imported into my Meteor app using:
mongorestore -h 127.0.0.1 --port 3001 -d meteor dump/mymongodb
Now it seems I can access any collection just find by using the collection name for example:
Meteor.publish 'works', ->
Works.find({}, {limit: 10, sort: {createdAt: -1}})
Seems to work, as we had a collection named works. I didn't even have to define it:
#Works = new Meteor.collection('works')
although it probably wouldn't hurt to define it.
But I am lost when it comes to the Meteor.users collection. We had a collection in our database called users, but I cannot access that one. How can I get our users collection from other mongodb into Meteor.users for the app?
PS. I can access the users collection directly from terminal using 'meteor mongo' and search db.users.findOne() but I cannot seem to access it from the code files.
You need collections to be defined in order to use them. Meteor.users is defined by the accounts packages (e.g. accounts-password). If you are not using any of those packages, you will need to define the collection like so:
#Users = new Mongo.Collection 'users'
or
#Meteor.users = new Mongo.Collection 'users'
I regularly do this in apps which talk to our database but which don't require any user interaction (db migrations, stats reporting, etc.).
Of course, without the accounts packages installed, you get none of the other user functionality, but that may not matter in your case.
Related
I have a collection that needs to be updated. There's a need to add new field and fill it out based on the existing field.
Let's say I have a collection called documents:
documents/{documentId}: {
existingField: ['foo', 'bar'],
myNewField ['foo', 'bar']
}
documents/{anotherDocumentId}: {
existingField: ['baz'],
myNewField ['baz']
}
// ... and so on
I already tried to fire up local cloud function from emulator that loops for each document and writes to production data based on the logic I need. The problem is that function can only live up to max of 30 seconds. What I need would be some kind of console tool that I can run as admin (using service-account) to quickly manage my needs.
How do you handle such cases?
Firebase does not provide a console or tool to do migrations.
You can write a program to run on your development machine that uses the one of the backend SDKs (like the Firebase Admin SDK) to query, iterate, and update the documents and let it run as long as you want.
There is nothing specific built into the API for this type of data migration. You'll have to update each document in turn, which typically involves also reading all documents (or at least their IDs).
While it is possible to do this on Cloud Functions, I find it easier to do it with a local Node.js script, as that doesn't have the runtime limits Cloud Functions imposes.
I have an app written in MeteorJS, the functionality is only for logged in users, and all the documents in Mongo have an userId field for each logged in user.
However, I want now to add a "demo" functionality, were on the landing page the user can click instead of "log on" a "try out the demo" button.
The main difference in functionality would be, that the "demo user" doesn't store anything in the MongoDb database and all data and operations are performed only on the local MiniMongo database.
Is there any easy way to achieve this?
I know about new Meteor.Collection(null) that it is only locally, but I define the collection on the global level of the app where I don't have access to Meteor.userId()' orthis.userId` so it would have to check on every place which collection to use.
Ended up with following approach:
On place were I define my collections (shared code between server and client) I define two collections:
var Docs = new Meteor.Collection("docs");
var DocsOffline = new MeteorCollection(null);
no in each meteor method I access the collection using following variable:
let docsSource = Meteor.userId() ? Docs : DocsOffline;
and then operate on docsSource
On the client in the getMeteorData mixin method I have similar approach to make the data available (I use ReactJS)
I want to have my application's admin code hosted on a completely different app that shares the same database. However, that means that my collections are defined, at least in the code, in the global namespace of my main application and not my admin application. How can I access my collections, that are in the database, without having the global variables defined in a file shared between the meteor server/client? For reference, I am using this article as the idea to set up my admin tools this way. admin article
To simplify the problem, let's say you have:
two applications: A and B
one shared collection: Posts
one shared database via MONGO_URL
Quick and Dirty
There's nothing complex about this solution - just copy the collection definition from one app to the next:
A/lib/collections.js
Posts = new Mongo.Collection('posts');
B/lib/collections.js
Posts = new Mongo.Collection('posts');
This works well in cases where you just need the collection name.
More Work but Maintainable
Create a shared local package for your Posts collection. In each app: meteor add posts.
This is a little more complex because you'll need to create a pacakge, but it's better for cases where your collection has a model or other extra code that needs to be shared between the applications. Additionally, you'll get the benefits of creating a package, like testing dependency management, etc.
Each application will have its own code but will share the same mongo db. You'll need to define the same collections (or a subset or even a superset) for the admin app. You can rsync certain directories between the two apps if that makes that process either but there isn't anything in Meteor that will do this for you afaik.
Or you could share data between the two servers using DDP:
var conn = DDP.connect('http://admin-server');
Tracker.autorun(function() {
var status = conn.status();
if(status.connection) {
var messages = new Mongo.Collection('messages', {connection: conn});
conn.subscribe('messages', function() { console.log('I haz messages'); });
}
});
This creates a local collection named messages that pulls data from the "admin server" over DDP. This collection only exists in memory - nothing is created in mongo. You can do this on the server or client. Definitely not the best choice for large datasets. Limit the data transfer with publications.
Does anyone know how to drop a collection safely in Meteor? There doesn't seem to be an API method for this. The collections are published, so I want to cleanup the associated data and functions (besides just removing the MongoDB collection).
Someone asked a similar question but no one actually answered it (just other concerns apart from dropping the collection).
Clarification: I need to do this from the meteor program at runtime.
You can drop a collection with the basic mongo shell command : db.collection.drop()
To do that, you have to connect to your mongo shell in your command line.
There is another easier way : Robomongo ( http://robomongo.org/ ) which is a really nice GUI to manage mongo db. Once logged on mongo, just right click on your collection and then > drop (and confirm of course).
For example, to log in on your local environment, give any name and skip login. The address should be localhost : 3001.
I have an meteor app "A" using accounts-base, accounts-ui, accounts-twitter, and accounts-weibo.
I decided to make another meteor app "B", that is basically same as the above but especially for mobile devices.
Are there any ways to change a database that accounts packages use on B, to A's?
It may be possible, though not absolutely sure. Something like this may work:
var connection = DDP.connect("http://other_server");
Meteor.users = new Meteor.Collection("users", { connection: connection });
If you get a 'collection is already defined error' you may have to fork accounts-base and use this in place of what is used for Meteor.users & it should be fine.
What it does is it pretends to be a DDP client for the other server, allowing your users from app B use the users collection from app A, yet have a separate database for itself.
THe other option is to share the same MONGO_URL as the other app, and you wouldn't have to worry about modifying the accounts-base package (if you have to)