i have a userSignUp and login System where a user is stored with his email address and password.
Later i want to add more information to this user, so i created a new data class on parse.com with the name "UserProfile" where i store the userObjectId from the user that has been signed up.
So now i want to update this user in the data class UserProfile but i just now the objectId from the user in the UserClass.
So i want to update like "update user where userObjectId = PFUser.currentUser().objectId"
i have this snippet of code already:
var query = PFQuery(className:"UserProfiles")
var userId = PFUser.currentUser()?.objectId?
query.whereKey("userObjectId", equalTo: userId)
//i don't think, that the following code is correct
query.getObjectInBackgroundWithId("xWMyZEGZ") {
(gameScore: PFObject?, error: NSError?) -> Void in
if error != nil {
println(error)
} else if let gameScore = gameScore {
gameScore["cheatMode"] = true
gameScore["score"] = 1338
gameScore.saveInBackground()
}
}
Assuming your "userObjectId" field is a string field and not a pointer field, then you can do this.
var query = PFQuery(className: "UserProfiles")
var userId = PFUser.currentUser()!.objectId
query.whereKey("userObjectId", equalTo: userId)
//here you would just find the results
query.findObjectsInBackgroundWithBlock {(objects: [AnyObject]?, error: NSError?) -> Void in
if error == nil {
//you have the user, assuming one but their could be more
//this will only return one user since you're using the objectID as a field and those are unique, so...
for user in objects! {
user["aColumnYouWishToUpdate"] = whatYouWishToUpdateTo
user["anotherColumnToUpdate"] = anotherUpdatedVariable
//do this for any columns you want updated
user.saveInBackground() //to save the newly updated user
}
} else {
//you have an error
}
}
Related
I am new to SwiftUI and I am currently practicing with Firebase Firestore. The problem that I am experiencing is when the user signs in, the code is unable to fetch the data (their first, last name, email and points) from the Firestore database, unless the user force closes the app and reopens it. Below is the code I have.
UserDataFetch.swift
import Foundation
import FirebaseAuth
import FirebaseFirestore
struct User {
let uid, firstName, lastName, email: String
let points: Int
}
class UserDataFetch: ObservableObject {
#Published var uname: User?
init() {
fetchCurrentUser()
}
private func fetchCurrentUser() {
guard let usID = Auth.auth().currentUser?.uid else {
return
}
Firestore.firestore().collection("users").document(usID).addSnapshotListener { snapshot, error in
if let error = error {
print("Failed to fetch", error)
return
}
guard let data = snapshot?.data() else {
return
}
let uid = data["uid"] as? String ?? ""
let firstName = data["firstName"] as? String ?? ""
let lastName = data["lastName"] as? String ?? ""
let points = data["points"] as? Int ?? 0
let email = data["email"] as? String ?? ""
self.uname = User(uid: uid, firstName: firstName, lastName: lastName, email: email, points: points)
}
}
}
Below is also the code from my login function. I am using #AppStorage("uid") var userID = "" to store and check if the user is logged in.
func loginUser() {
Auth.auth().signIn(withEmail: email, password: password) { authResult, error in
if let error = error {
print(error)
return
}
if let authResult = authResult {
print(authResult.user.uid)
userID = authResult.user.uid
}
}
}
As I am still new I tried looking into the documentation of Firebase, I watched videos on YouTube, but I am still unable to come to a resolution. Any help would be greatly appreciated. Thank you!
How to return user if based on facebook user ID it already exist, and create a new user if not exist in Vapor? You can see how I tried fetch data, but get error.
final class User: Content {
var id: Int?
var fbId: String
init(id: Int? = nil, fbId: String) {
self.id = id
self.fbId = fbId
}
}
router.get("user") { (request) -> Future<User> in
return Future.map(on: request) { () -> User in
let fbId = try request.query.get(String.self, at: "fbId")
return User.query(on: request).filter(\.fbId == fbId).first().map { (user) -> (U) in
if user == nil {
user = User(fbId: fbId)
}
return user
}
}
}
You have a few things going on here. To start with you don't need the first Future.map - not sure what that's doing.
Then you have the issue of the compiler - you have to return the same type in each closure and the function, which is awkward because if you already have a user you can return that, if you don't you need to create and save one, which returns Future<User>, which is not the same to User.
So to answer your question, U there should be User, but really you want to change first().map to first().flatMap in which case U becomes Future<User>. Then you can do something like:
router.get("user") { req -> Future<User> in
let fbID = try req.query.get(String.self, at: "fbId")
return User.query(on: req).filter(\.fbId == fbID).first().flatMap { user in
let returnedUser: Future<User>
if let foundUser = user {
returnedUser = req.future(foundUser)
} else {
let newUser = User(fbId: fbID)
returnedUser = newUser.save(on: req)
}
return returnedUser
}
}
To solve your problems. Hope that helps!
.map { (user) -> (U) in
This defines that you get a user into the closure and have to return a U. In your example you want to return a User (so change U to User).
If you want to create the user (in case it is nil) you probably also want to store it in the database? If that's the case, you'll have to change map to flatMap and update like this:
.flatMap { (user) -> EventLoopFuture<User> in
if user == nil {
return User(fbId: fbId).save(on: req)
}
return req.future(user)
}
I'm having some issue querying parse.com data. Here is my current code.
I have a 'Classifieds' parse "table" which contains several fields. One of those is 'user' of type Pointer<_User> and contains the userid of the user who created an ad.
In my query, I wish to get all classifieds for a specific user. 'userid' of that user equals to 'og8wGxHKOm'.
The query always returns null. Though, there is at least one ad (record) for that specific user as shown on the screen capture.
What am I missing ? - Working with latest Parse .Net SDK
namespace FindAllAds
{
public partial class _Default : Page
{
protected async void Page_Load(object sender, EventArgs e)
{
string x = await MyAds();
parselabel.Text = x;
}
private async Task<string> MyAds()
{
var query = ParseObject.GetQuery("Classifieds")
.WhereEqualTo("user", ParseObject.CreateWithoutData("User", "og8wGxHKOm"));
IEnumerable<ParseObject> results = await query.FindAsync();
//for testing only
string myString = "";
foreach (var value in results)
{
myString += value["title"] + "<br/>";
}
return myString;
}
}
}
screen capture
The name of the user class is "_User", so:
var userPointer = ParseObject.CreateWithoutData("_User", "og8wGxHKOm");
var query = ParseObject.GetQuery("Classifieds").WhereEqualTo("user", userPointer);
I'm trying to get the userid of the currently logged in user. Here is my code:
public int GetUserID(string _UserName)
{
using (var context = new TourBlogEntities1())
{
var UserID = from s in context.UserInfoes
where s.UserName == _UserName
select s.UserID;
return Int32.Parse(UserID.ToString()); //error is showing here
}
}
I'm calling the method from my controller using this:
public ActionResult NewPost(NewPost model)
{
var Business = new Business();
var entity = new Post();
entity.PostTitle = model.PostTitle;
entity.PostStory = model.PostStory;
entity.UserID = Business.GetUserID(User.Identity.Name);
Business.NewPost(entity);
Business.ViewPost(entity);
return View("ViewPost", model);
}
The error is showing as "input string is not in correct format". Please help. Thanks.
Your query returns an IEnumerable. You need to get only the single record:
using (var context = new TourBlogEntities1())
{
var userIds = from s in context.UserInfoes
where s.UserName == _UserName
select s.UserID;
return userIds.Single();
}
By the way the .Single() method will throw an exception if there are more than 1 records matching the criteria. Hopefully you have an unique constraint on the Username field inside your database.
CreatedBy = this.HttpContext.User.Identity.Name,
I am having trouble creating generic delete method, not even sure if this possible. I have a delete method which will delete record from db based on entity type and row id value (pk),
that works ok but it needs to know the type in advance. In some cases I can only get object
type using Object.GetType() at runtime (like from viewstate) and that is when trouble starts. Here is my method that works when type is known, is there a way to modify it so that it will use Object.GetType() instead of T ?
public void Delete<T>(long Id) where T : class,new()
{
#region PerformaneMonitor
IDbEntities Db=null;
T item=null;
try
{
Db = this.GetDatabase();
item = new T();
Type itemType = item.GetType();
EntityContainer entityContainer = Db.MetadataWorkspace.GetEntityContainer(Db.DefaultContainerName, DataSpace.CSpace);
var entity = entityContainer.BaseEntitySets.First(b => b.ElementType.Name == itemType.Name);
if (entity.ElementType.KeyMembers.Count == 0)
{
throw new Exception("Unable to delete a record witout unique id");
}
string PrimaryKeyName = entity.ElementType.KeyMembers[0].Name;
itemType.GetProperty(PrimaryKeyName).SetValue(item, Id, null);
}
catch (Exception ex)
{
Close(Db);
throw(ex);
}
this.Delete<T>(item, Db);
Close(Db);
#region PerformaneMonitor
}
so I am trying to convert it to Delete(object EntityType,long Id ) but no luck.
Here what it looks like :
public void Delete(object target,long Id)
{
#region PerformaneMonitor
IDbEntities Db = null;
try
{
Db = this.GetDatabase();
Type itemType = (Type)target;
EntityContainer entityContainer = Db.MetadataWorkspace.GetEntityContainer(Db.DefaultContainerName, DataSpace.CSpace);
var entity= entityContainer.BaseEntitySets.First(b => b.ElementType.Name == itemType.Name);
if (entity.ElementType.KeyMembers.Count == 0)
{
throw new Exception("Unable to delete a record witout unique id");
}
string PrimaryKeyName = entity.ElementType.KeyMembers[0].Name;
itemType.GetProperty(PrimaryKeyName).SetValue(target, Id, null);
}
catch (Exception ex)
{
Close(Db);
throw (ex);
}
this.Delete(target, Db);
Close(Db);
//_method_tag_end_
#region PerformaneMonitor
}
I am getting 'Object does not match target type' on
this line:
itemType.GetProperty(PrimaryKeyName).SetValue(target, pkey, null);
the object target is actaul instance of specific type which I do in the calling method from Type of object and using reflection and pass to this function but still I have no idea what type it is at run time.
If someone can help it will be greatly appreciated.
It sounds like you should do something along these lines: (Sorry, can't test to make sure it works as written.)
object o = itemType.GetProperty(PrimaryKeyName);
MethodInfo mi = o.GetType().GetMethod("SetValue");
mi.Invoke(o, new object [] { Id, null });