I'm trying to wrap my head around firebase, and one issue I can't seem to work out is how mass updates occur.
Lets say I have 1,000 users and they all have "user_role": "member"
And I decide to update all 1,000 users to "user_role":"paid-member"
in SQL I can just do UPDATE users SET user_role = 'paid-member' ... So what's the Firebase equivalent?
Or more importantly, how would I accomplish something like this in firebase...
UPDATE users SET user_role = 'paid-member' WHERE user_role = 'member'
Unfortunately, it's not possible to do this without knowing the list of users beforehand. If you had all the usernames in an array, you could do something like this:
var usernames = [...];
for (var i = 0; i < usernames.length; i++) {
var ref = new Firebase("https://myfirebase.firebaseio.com/users/" + usernames[i]);
ref.child("user_role").set("paid-member");
}
You'll have to retrieve the list of usernames first using a child_added or value event handler.
Related
I'm working on the Flutter app where users can save multiple addresses. Previously I used a real-time database and it was easier for me to push data in any child with a unique Id but for some reason, I changed to Firestore and the same thing want to achieve with firestore. So, I generated UUID to create unique ID to append to user_address
This is how I want
and user_address looks like this
And this is how it's getting saved in firestore
So my question Is how I append data with unique id do I have to create a collection inside users field or the above is possible?
Below is my code I tried to set and update even user FieldValue.arrayUnion(userServiceAddress) but not getting the desired result
var uuid = Uuid();
var fireStoreUserRef =
await FirebaseFirestore.instance.collection('users').doc(id);
Map locationMap = {
'latitude': myPosition.latitude,
'longitude': myPosition.longitude,
};
var userServiceAddress = <String, dynamic>{
uuid.v4(): {
'complete_address': completedAddressController.text,
'floor_option': floorController.text,
'how_to_reach': howtoreachController.text,
'location_type': locationTag,
'saved_date': DateTime.now().toString(),
'user_geo_location': locationMap,
'placeId': addressId
}
};
await fireStoreUserRef.update({'user_address': userServiceAddress});
If I use set and update then whole data is replaced with new value it's not appending, so creating a collection is the only solution here and If I create a collection then is there any issue I'll face?
You won't have any issues per se by storing addresses in a separate collection with a one-to-many relationship, but depending on your usage, you may see much higher read/write requests with this approach. This can make exceeding your budget far more likely.
Fortunately, Firestore allows updating fields in nested objects via dot notation. Try this:
var userServiceAddress = {
'complete_address': completedAddressController.text,
'floor_option': floorController.text,
'how_to_reach': howtoreachController.text,
'location_type': locationTag,
'saved_date': DateTime.now().toString(),
'user_geo_location': locationMap,
'placeId': addressId
};
await fireStoreUserRef.update({'user_address.${uuid.v4()}': userServiceAddress});
I am the following. As a user registers his account name and password are put into an existing table. Then his id gets read from that table and another table is made using that id as the tablename.
Now inserting works great but reading the Id from that table seems to give me some problems.
Now it would be great if I was even able to get that id to display on my webpage. i feel like when I am able to do that I can just do something like CREAT TABLE + #Id + etc.
This is what I have so far
var gebruikersnaam = Request.Form["registnaam"];
var wachtwoord = Request.Form["registpassword"];
if (IsPost && Request.Form["registreren"] == "Registreren")
{
var insertCommand = db.Execute("INSERT INTO Accounts (gebruikersnaam, wachtwoord) VALUES(#0, #1)", gebruikersnaam, wachtwoord);
var id = db.Query("SELECT * FROM Accounts WHERE gebruikersnaam = #0", gebruikersnaam);
Response.Write(#id);
}
And this is what the Response.Write(#id) shows me on the webpage:
System.Collections.ObjectModel.ReadOnlyCollection`1[System.Object]
Try merging the create and select query into one.
INSERT INTO Accounts (gebruikersnaam, wachtwoord)
OUTPUT Inserted.Id
VALUES('value1', 'value2')
Getting the Id using a separate query could be a problem in the future especially if the data becomes large, doing this optimize the speed of data retrieval in DB like getting the Id of an inserted record.
I have a Google drive table data source which stores list of open positions. Now in the data source I've set "Query per size" field to 10 so that I can get 10 records per page. I've added a Pager as well to show pagination.
My query is I want to display like "Page 1 of X" to my end users and this X will vary based on certain search filters. What will the best way to achieve this in Appmaker?
I've tried counting total records in a data source as per below code but every time updating that with the search criteria and recounting it is not a proper solution.
//Server side
var newQuery = app.models.Company.newQuery();
var records = newQuery.run();
var totalCount =0;
for(var i=0;i<records.length;i++)
{
totalCount=totalCount+1;
}
return totalCount;
In case you don't have any filters in your table your server code can be as simple as
// Server script
function getPagesCount(pageSize) {
var recordsCount = app.models.MyModel.newQuery().run().length;
var pagesCount = Math.ceil(recordsCount / pageSize);
return pagesCount;
}
As an alternative you can consider creating Calculated Model with a single field PagesCount.
In case you have some filters associated with the table then you'll need to run the query for the pages number with exact same filters.
Most likely the entire setup will not work effectively with Drive Tables since there is no way to query records number without querying records themselves. With Cloud SQL data backend one can create Calculated SQL Model with lightweight native SQL query (here :PageSize is query parameter which should be equal to the query.limit of the actual datasource):
SELECT
Ceil(COUNT(1) / :PageSize) AS RecordsNumber
FROM
TableName
WHERE
...
I've achieved this using Calculated Model as suggested by Pavel.
Steps :
Create a calculated data source with one field count.
In that data source add one parameter searchQuery. This will contain users filter going forward. Currently I have only one search query in which user can search many things. So I've added one parameter only.
In this data source add following server script.
Code:
// Server script
function getTotalRecords(query) {
var receivedQuery = query.parameters.searchQuery;
// console.log('Received query:' + query.parameters.searchQuery);
var records = app.models.Company.newQuery();
records.parameters.SearchText = query.parameters.searchQuery;
if(receivedQuery !== null) {
records.where = '(Name contains? :SearchText or InternalId contains? ' +
':SearchText or LocationList contains? :SearchText )';
}
var recordsCount = records.run().length;
var calculatedModelRecords = [];
var draftRecord = app.models.RecordCount.newRecord();
draftRecord.count = ''+recordsCount;
calculatedModelRecords.push(draftRecord);
return calculatedModelRecords;
}
.
On the Appmaker page bind a label with this data source.
On search query/your filter applied event add following code which Reload this data source and assign value to Parameter.
// Client script
function updateRecordCount(newValue) {
var ds = app.datasources.RecordCount;
ds.query.parameters.searchQuery = newValue;
ds.unload();
ds.load();
}
I'm working on a project (using Firebase for the backend) where we want to associate an arbitrary amount of values with a particular key. We would like to delete/add values freely, and I'm having trouble thinking of a solution for this without using string concatenation, which is not ideal for deletion. Any ideas on a way to handle this?
You shouldn't have any trouble setting up your Firebase location as
--keys
----$key
------{someValue}: true
Where $key corresponds to whatever key you're storing, and then you'd just set children values with a boolean "true". Assuming JavaScript, you'd have something similar to:
var myKey = 'someKey';
var someVal = 'someVal';
var someOtherVal = 'foo';
var fb = new Firebase('https://xyz.firebaseio.com/keys/' + myKey);
fb.child(someVal).set(true);
fb.child(someOtherVal).set(true);
Now you can read all of these attributes from the fb reference easily enough.
To delete you could do the following:
var fb = new Firebase('https://xyz.firebaseio.com/keys/' + myKey);
fb.child(someVal).remove();
I'm struggling to get a collection of records using L2E. Here's the model view:
http://pascalc.nougen.com/stuffs/aspnet_linq_model2.png
I have a user identifier, which is associated to 1 or many UserGroup which themselves are linked to TestCase. I would like to get all TestCases of all groups the user id X is associated to.
I also notice that I don't get all Project for users that are associated to 2 (or more).
Here's how I do so far:
QASModel.QASEntities qasEntities = new QASModel.QASEntities();
QASModel.User authenticatedUserEntity = (from u in qasEntities.Users
where u.ID.Equals(authenticatedUserId)
select u).FirstOrDefault();
// Get the authenticated user usergroups
var usergroup = authenticatedUserEntity.UserGroups.FirstOrDefault();
// Get all testcases of all user group the authenticated user is associated to
var allTestcases = usergroup.TestCases;
// Get the authenticated user projects based on it's usergroup(s)
var authenticatedUserProjects = usergroup.Projects;
authenticatedUserProjects give back only 1 project, where the user is linked to 2 projects.
And allTestcases gives back no result, although there are about 8 entries in TestCases associated to a project associated to one of the same UserGroup the user belongs to.
Thanks
I think your problem is in this line:
var usergroup = authenticatedUserEntity.UserGroups.FirstOrDefault();
Shouldn't your code get all UserGroups of that User? The above line will return only 1 UserGroup, this is, if the user belongs to more than 1 UserGroup the 2nd one won't be returned.
To correct this:
var userTestCases = new List<TestCase>();
var userProjects = new List<Project>();
foreach(UserGroup ug in authenticatedUserEntity.UserGroups)
{
userTestCases = userTestCases.Concat(ug.TestCases);
// Get the authenticated user projects based on it's usergroup(s)
userProjects = userProjects.Concat(ug.Projects);
...
}
var usergroup = authenticatedUserEntity.UserGroups.FirstOrDefault();
probably is wrong, since you want all usergroups the user is associated with.
In any case you can easily revert the query to work like this
var testcases = from tc in new QASModel.QASEntities().TestCases
where tc.UserGroup.UserId == USERID
select tc
This way you won't have to execute multiple queries to get all test cases, each FirstOrDefault or ToList or ForEach will actually execute the query.