BackendlessException: An item with the same key has already been added. Key: Posts

Hello everyone,

Hoping someone can help me out here :confused: Thanks in advance.

Expected Behavior

1.Works fine when task is run first time round.
2.When same task is executed from another script with different properties and where clause, task should run as expected.

Actual Behavior

BackendlessException: An item with the same key has already been added. Key: Posts BackendlessAPI.Engine.Invoker.InvokeSync[T] (System.String className, System.String methodName, System.Object[] args, System.Boolean enableUnderFlowInspection) (at <d4df01d4d1054503b34e66ef22b60412>:0) BackendlessAPI.Service.PersistenceService.Find[T] (BackendlessAPI.Persistence.DataQueryBuilder dataQueryBuilder) (at <d4df01d4d1054503b34e66ef22b60412>:0) BackendlessAPI.Data.DataStoreFactory+DataStoreImpl1[T].Find (BackendlessAPI.Persistence.DataQueryBuilder dataQueryBuilder) (at :0)`

1.Task fails with the above log, even when disposing task after completion
2. Therefore can only find posts once.

if (Task.CompletedTask.Status == TaskStatus.RanToCompletion) { Task.CompletedTask.Dispose(); }

Reproducible Test Case

`async void LoadUserPosts(string objectId)
{
DataQueryBuilder queryBuilder = DataQueryBuilder.Create();
queryBuilder
.SetPageSize(10)
.SetOffset(0)
.SetWhereClause($“ownerId = ‘{objectId}’”)
//.ExcludeProperties(presentPostIds)
.AddAllProperties()
.ExcludeProperty(“likes”)
.AddProperty(“Count(likes) as totalLikesCount”)
.AddGroupBy(“objectId”)
.AddSortBy(“created DESC”);

            IList<Posts> result = await Backendless.Data.Of<Posts>().FindAsync(queryBuilder);

}`

Hello @Marco_De_Freitas.
Can you share your application id?

Regards, Nikita.

Hi Nikita,

The app ID is F9F73608-F7DB-9227-FFFC-C9B5CE37F800

Thanks

Hello @Marco_De_Freitas!

And one more question to clarify.
In which application are you getting the error (Xamarin, Console Application, Unity, etc.)?

@Marco_De_Freitas, I tried to reproduce the error using your example.
The program ended without errors.
If I did something wrong, correct me, please.

  DataQueryBuilder queryBuilder = DataQueryBuilder.Create();
  queryBuilder.SetPageSize( 10 )
              .SetOffset( 0 )
              .SetWhereClause( $"ownerId='F6260C98-80FF-4AF0-8CFF-7FB87571A54E'" )
              .AddAllProperties()
              .ExcludeProperties( "likes" )
              .AddProperty( "Count(likes) as totalLikesCount" )
              .AddGroupBy( "objectId" )
              .AddSortBy( "created DESC" );

  IList<Posts> result = new List<Posts>();
  Task.Run( async () =>
    {
      result = await Backendless.Data.Of<Posts>().FindAsync( queryBuilder );
    } ).Wait();

I called this code from two different places in the program.

Regards, Nikita.

Hi Nikita,

I am using Unity 2019.4 LTS

Hello, @Marco_De_Freitas.

Can you provide a simple project that repeats the problem?

Regards, Nikita.

Hi @Nikita_Fedorishchev

Many thanks for your assistance.

I was able to resolve the issue, it seems that the Backendless DataQueryBuilder holds a list of recently queried posts in cache, therefore I had to make sure not to query the same posts again.

Here’s the solution:

public async void LoadUserPosts(string objectId)
{
    //check for existing posts in dictionary
    List<string> presentPostsList = new List<string>();
    foreach(var post in mainPage.postFeedPage.followingPosts)
    {
        //since we querying a single users posts, only find posts owned by the user
        if(post.Value.ownerId == viewingUser.objectId)
        {
            //add existing posts to a temp list to generate where clause
            presentPostsList.Add(post.Value.objectId);

            //add existing posts to dictionary and add them to view
            allUserPosts.Add(post.Key, post.Value);
            StartCoroutine(LoadPostMedia(post.Key));
        }
    }
    //generate where clause including ownerId and all existing post ids to exclude from query
    string[] presentPostIds = presentPostsList.ToArray();
    string whereClause = $"ownerId = '{objectId}' ";
    foreach (var postid in presentPostIds)
    {
        whereClause += $" AND objectId != '{postid}' ";
    }

    //create data query
    DataQueryBuilder queryBuilder = DataQueryBuilder.Create();
    queryBuilder
        .SetPageSize(10)
        .SetOffset(0)
        .SetWhereClause(whereClause)
        .AddAllProperties()
        .ExcludeProperty("likes")
        .AddProperty("Count(likes) as totalLikesCount")
        .AddGroupBy("objectId")
        .AddSortBy("created DESC");

    //find all results
    IList<Posts> result = await Backendless.Data.Of<Posts>().FindAsync(queryBuilder);

    //add all queried posts to dictionary and add to view
    foreach (var obj in result)
    {
        allUserPosts.Add(userPostCount, obj);
        StartCoroutine(LoadPostMedia(userPostCount));
        userPostCount++;
    }
}

I’m not sure if this is the best approach but it works, could you kindly advise if there a way to access that data from the cache directly?

Thanking you.